[英]Can I access the interface of a COM object from different threads?
我可以訪問像這樣的服務的主工作線程中的IAudioEndpointVolume接口(省略錯誤檢查):
CoInitialize(NULL);
CoCreateGuid(&g_guidMyContext);
CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, IID_IMMDeviceEnumerator, (void**)&m_pEnumerator);
IMMDevice *pEndpoint = NULL;
m_pEnumerator->GetDevice(&deviceID[0], &pEndpoint);
IAudioEndpointVolume *pAudioVol = NULL;
pEndpoint->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, NULL, (void**)&pAudioVol);
CAudioEndpointVolumeCallback *pVolumeCallback = new CAudioEndpointVolumeCallback(pAudioVol, 100, TRUE, m_debugLog, m_logMutex);
然后, CAudioEndpointVolumeCallback
類將IAudioEndpointVolume
指針存儲在成員變量中,並在其構造函數中對其調用RegisterControlChangeNotify(this)
。
此類還可以啟動一個線程,以便在短時間內將音量從一個值平滑地更改為另一個值。 所以最后我從不同的線程調用IAudioEndpointVolume
接口。 一般來說,所有這些都按預期工作,但我在某些邊緣情況下遇到了一些奇怪的行為。 當我再次檢查代碼時,我偶然發現了MSDN文檔中有關線程的注釋(我沒有任何關於COM對象的經驗),並想知道我所做的是否正確。
那么,使用上面的代碼從不同的線程調用IAudioEndpointVolume
接口是否安全? 我是否必須使用互斥鎖來保護這些呼叫?
CoInitialize(NULL)
初始化單線程單元(STA)和接口指針,只有[應該]在此線程上有效。 您可以通過GIT或者通過此線程上的CoMarshalInterThreadInterfaceInStream
將它們傳遞給另一個線程,並通過目標線程上的CoGetInterfaceAndReleaseStream
獲取它的“重復”,您將在其中使用它。
根據所討論的接口指針背后的實現,您最終可能獲得相同的指針(在這種情況下,整個技巧將等於簡單地使用另一個線程上的指針),但是在一般情況下這不安全。
另一種選擇是使用MTA(而不是STA),然后允許您在所有/任何MTA線程之間直接傳遞指針。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.