I made a multithread win32 APP like this
INT WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR pCmdLine, INT nCmdShow)
{
....
// EXECUTE FUNCTION1 IN ANOTHER THREAD
DWORD thid;
HANDLE th = CreateThread(NULL, NULL, FUNCTION1, (LPVOID)&hwnd, NULL, &thid);
// window
WNDCLASS wndc = {};
wndc.lpfnWndProc = WndProc;
wndc.hInstance = hInstance;
wndc.lpszClassName = PROGWND_CLASS_NAME;
wndc.style = CS_NOCLOSE;
const int widt = 380, heigh = 140;
const HWND hwnd = CreateWindowEx(
0,
PROGWND_CLASS_NAME,
PROGWND_WINDOW_NAME,
WS_POPUP| WS_CAPTION,
GetSystemMetrics(SM_CXSCREEN)/2-widt /2,
GetSystemMetrics(SM_CYSCREEN)/2-heigh/2,
widt, heigh,
nullptr, nullptr, hInstance, nullptr
);
ShowWindow(hwnd, SW_SHOWDEFAULT);
// message loop
MSG msg;
while (GetMessage(&msg, hwnd, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
The following code is run in FUNCTION1
CoInitialize(nullptr);
IShellLink* psl;
HRESULT hr = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLink,
(LPVOID*)(&psl));
When it comes to CoCreateInstance
an exception will be thrown.
In my case it's this:
Exception thrown at 0x7740E3BC (ntdll.dll) in APP.exe: 0xC0000005: Access violation reading location 0x007E4888.
If I run FUNCTION1
just in the main thread then this will not happen. Don't know why.
I think CoInitialize(nullptr);
has already initialized the COM library on the new thread as STA, therefore has no conflict with the main-thread.
I also mentioned I created a window and have a message loop in the main thread (the message loop is for that window). Looks like the problem has relationship to the message loop?
Call Stack:
ntdll.dll!@RtlpLowFragHeapAllocFromContext@8() Unknown
ntdll.dll!_RtlAllocateHeap@12() Unknown
ole32.dll!operator new(unsigned int size) Line 31 C++
ole32.dll!CCache::AddElement(unsigned long iHashValue, unsigned char * pbKey, unsigned short cbKey, unsigned short * pfValueFlags, IUnknown * pUnknown, IUnknown * * ppExistingUnknown) Line 150 C++
ole32.dll!CCache::AddElement(unsigned long iHashValue, unsigned short cKeys, unsigned char * * pbKey, const unsigned short * cbKey, unsigned short * pfValueFlags, IUnknown * pUnknown, IUnknown * * ppExistingUnknown) Line 328 C++
ole32.dll!CComCatalog::GetClassInfoInternal(unsigned long flags, IUserToken * pUserToken, const _GUID & guidConfiguredClsid, const _GUID & riid, void * * ppv, void * pComCatalog) Line 2876 C++
ole32.dll!CComCatalog::GetClassInfoW(unsigned long flags, IUserToken * pUserToken, const _GUID & guidConfiguredClsid, const _GUID & riid, void * * ppv) Line 726 C++
ole32.dll!LookForConfiguredClsid(const _GUID & RefClsid, _GUID & rFoundConfClsid, unsigned long dwActvFlags) Line 1085 C++
ole32.dll!ICoCreateInstanceEx(const _GUID & OriginalClsid, IUnknown * punkOuter, unsigned long dwClsCtx, _COSERVERINFO * pServerInfo, unsigned long dwCount, unsigned long dwActvFlags, tagMULTI_QI * pResults, ActivationPropertiesIn * pActIn) Line 1198 C++
ole32.dll!CComActivator::DoCreateInstance(const _GUID & Clsid, IUnknown * punkOuter, unsigned long dwClsCtx, _COSERVERINFO * pServerInfo, unsigned long dwCount, tagMULTI_QI * pResults, ActivationPropertiesIn * pActIn) Line 332 C++
ole32.dll!CoCreateInstanceEx(const _GUID & Clsid, IUnknown * punkOuter, unsigned long dwClsCtx, _COSERVERINFO * pServerInfo, unsigned long dwCount, tagMULTI_QI * pResults) Line 175 C++
ole32.dll!CoCreateInstance(const _GUID & rclsid, IUnknown * pUnkOuter, unsigned long dwContext, const _GUID & riid, void * * ppv) Line 120 C++
User contributions licensed under CC BY-SA 3.0