Basically the usage pattern is:
1. get the module handle (GetModuleHandleEx)
2. create the thread (CreateThread)
3. If COM, CoInitialize a new apartment for the thread
4. Do work
5. If COM, CoUninitialize
6. FreeLibraryAndExitThread with the handle gotten in #1
7. Return
Steps 1-2, The thread creator would do something like this:
if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)&Class::ThreadProc , &s_hModule))
hr = HRESULT_FROM_WIN32( GetLastError() );
if (S_OK == hr) {
if (s_hThread)
CloseHandle(s_hThread);
s_hThread = CreateThread(NULL, 0, ThreadProc, this, 0, &s_dwThreadID);
if (!s_hThread) {
hr = HRESULT_FROM_WIN32(::GetLastError());
FreeLibrary( s_hModule );
}
}
In my case, the bug was in the GetModuleHandleEx. Take heed that if you are using the GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRES flag, then the second parameter should an address inside of your DLL; I have read that &__ImageBase or the HINSTANCE passed into DllMain should also do the trick. Also the third parameter will be used inside the thread proc.
Steps 3-7:
DWORD WINAPI Class::ThreadProc(void *pv)
{
if (S_OK == CoInitializeEx( NULL, COINIT_MULTITHREADED)) {
//...
// do work here
CoUninitialize();
}
FreeLibraryAndExitThread(s_hModule, 0);
return 0;
}
As always, read the documentation to go deeper in the topic.
No comments:
Post a Comment