CRITICAL_SECTION
のように、静的に初期化することは可能pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER
ですか?
言い換えれば、CでCRITICAL_SECTION
ライブラリ内のグローバルをいじる必要なく初期化することは可能DllMain
ですか?
CRITICAL_SECTION
のように、静的に初期化することは可能pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER
ですか?
言い換えれば、CでCRITICAL_SECTION
ライブラリ内のグローバルをいじる必要なく初期化することは可能DllMain
ですか?
はい、単純に DLL_PROCESS_ATTACH で初期化し、DLL_PROCESS_DETACH で削除します
CRITICAL_SECTION g_cs = {0};
BOOL WINAPI DllMain(
HINSTANCE hinstDLL, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpReserved ) // reserved
{
// Perform actions based on the reason for calling.
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
// Initialize once for each new process.
// Return FALSE to fail DLL load.
InitializeCriticalSection(&g_cs);
break;
case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
break;
case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
break;
case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
DeleteCriticalSection(&g_cs);
break;
}
return TRUE; // Successful DLL_PROCESS_ATTACH.
}
参考文献:
はい!ただし、プロセスごとに 1 回だけ実行する必要があります。ただし、これは通常、DLLMain
switch( fdwReason )
ステートメントの DLL_PROCESS_ATTACH ケースを使用することによって実現するのが最も簡単です。
以前のバージョンでの別の可能性は、初期化関数へのポインターをユーザー定義のグローバル初期化子として設定するようリンカーに指示することです。これについては、次のような議論があります。
http://msdn.microsoft.com/en-us/library/bb918180.aspx
以下に例を示します。
CRITICAL_SECTION criticalSection;
static void __cdecl Initialize(void) {
InitializeCriticalSection(&criticalSection);
}
#pragma section(".CRT$XCU", read)
__declspec(allocate(".CRT$XCU"))
const void (__cdecl *pInitialize)(void) = Initialize;
Raymond Chen からの上記の回答は、この問題を解決しますPTHREAD_MUTEX_INITIALIZER
。
これは Vista 以降でのみ動作することに注意してください --- @rkosegi
を使用して独自の
InitOnceExecuteOnce
関数をInterlockedCompareExchange
作成することにより、古いバージョンの Windows でこれを行うことができます。--- @RaymondChen