● ldstr.dll

マルチスレッドで ldstr.dll を使用する場合

非同期の場合、スレッドが予測した処理順にならない事があるので、floatex_ldstr_term を実行するタイミングに注意してください。
マルチスレッドでは、「メインの初期化処理時に floatex_ldstr_init 、終了処理時に floatex_ldstr_term を行う方法」は重要です。

例.

#include <windows.h>
#include <process.h>
#include <stdio.h>
#include "floatex.h"

typedef unsigned    (__stdcall *THREAD_ROUTINE)(void *);

typedef struct {
    FLOATEX         val;
    char            format[16];
} INFO,*PINFO;

/* スレッドの処理 */
unsigned __stdcall  thread(PINFO pinf)
{
    char        buf[32];
    int         i;

    /*
      渡されたFLOATEX値を文字列に変換し、500 ms 間隔で表示する事を
      20 回繰り返します
    */
    i = 20;
    do{
        floatex_ldstr_ldtoa(pinf->val,buf);
        printf(pinf->format,buf);
        Sleep(500);
    }while(--i);

    return 1;
}

#define THREAD_CNT      5 /* スレッド数 */

int __cdecl     main(void)
{
    HANDLE          hThread[THREAD_CNT];
    INFO            inf[THREAD_CNT + 1];
    unsigned        threadid;
    unsigned int    oldcw;
    int             i;

    if (!floatex_ldstr_init()){ /* ldstr の初期化 */
        printf("ldstr 初期化エラー\n");
        return 0;
    }

    oldcw = floatex_storecw();
    floatex_loadcw(FEX_PC_64 | FEX_RC_NEAR | FEX_MCW_EM);

    /* 情報とスレッドの生成 */
    i = 0;
    while(1){
        sprintf(inf[i].format,"%%%ds\n",i + 1);
        floatex_longto(i,inf[i].val);

        if (i >= THREAD_CNT)
            break;

        /*
          実行タイミングのばらつきを出来るだけ抑えたいので、
          生成と実行は別に行う
        */
        hThread[i] = (HANDLE)_beginthreadex(
            NULL,0,(THREAD_ROUTINE)thread,(void *)(inf + i),
            CREATE_SUSPENDED,&threadid);
        i++;
    }

    /* 一時停止の解除 */
    i = 0;
    do{
        ResumeThread(hThread[i]);
    }while(++i < THREAD_CNT);

    thread(inf + i); /* メインスレッドも処理に参加 */

    /*
      メインスレッドが最後に処理を開始しますが、完了はメインスレッドが
      最後になるとは限りません。
    */

    /* 全てのスレッド処理が完了するまで待機 */
    WaitForMultipleObjects(THREAD_CNT,hThread,TRUE,INFINITE);

    /* ハンドルのクローズ */
    i = 0;
    do{
        CloseHandle(hThread[i]);
    }while(++i < THREAD_CNT);

    floatex_ldstr_term(); /* ldstr 解放 */
    floatex_loadcw(oldcw);

    return 0;
}

何らかの理由により、メイン処理に floatex_ldstr_init 、floatex_ldstr_term を置けない場合は、一つのスレッドだけで ldstr.dll を使用する構成にするか、スレッドの同期を取ってから floatex_ldstr_term を実行してください。