簡體   English   中英

我可以從不同的線程訪問COM對象的接口嗎?

[英]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接口是否安全? 我是否必須使用互斥鎖來保護這些呼叫?

我有點困惑,我不確定我是否真的理解COM線程模型行為

CoInitialize(NULL)初始化單線程單元(STA)和接口指針,只有[應該]在此線程上有效。 您可以通過GIT或者通過此線程上的CoMarshalInterThreadInterfaceInStream將它們傳遞給另一個線程,並通過目標線程上的CoGetInterfaceAndReleaseStream獲取它的“重復”,您將在其中使用它。

根據所討論的接口指針背后的實現,您最終可能獲得相同的指針(在這種情況下,整個技巧將等於簡單地使用另一個線程上的指針),但是在一般情況下這不安全。

另一種選擇是使用MTA(而不是STA),然后允許您在所有/任何MTA線程之間直接傳遞指針。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM