我有一个多线程 C++Builder GUI 应用程序,它通过 COM 与第三方应用程序通信。
我需要从多个线程调用 COM 对象的方法,并且我使用互斥锁来保护访问。显然,主 GUI 线程必须使用 STA 模型,但我的工作线程需要使用 MTA。 COM 对象是在 MTA 线程中构造的。
由于 MTA/STA 不匹配,除了从 GUI 线程访问 COM 对象之外,一切正常。
我读过一些有关编组的内容,但没有尝试实现它,因为我看到的示例似乎需要不同的访问语义,具体取决于当前的公寓模型,我真的很想拥有这样的代码(来自程序员的POV)并不关心当前的公寓模型。
那么,是否有一种惯用的方法来编写对“同一”对象进行操作但可以从 STA 和 MTA 线程调用的 COM 代码?
I have a multi-threaded C++Builder GUI app, which communicates with a third-party app via COM.
I need to call methods of the COM object from several threads, and I'm protecting access with a mutex. Apparently, the main GUI thread must use STA model, but my worker threads need to use MTA. The COM object is constructed in an MTA thread.
Everything works fine except access to the COM object from the GUI thread, due to the MTA/STA mismatch.
I've read a bit about marshalling, but haven't tried to implement it, because the examples I've seen seem to require different access semantics depending the the current apartment model, and I really would like to have code that (from a programmer's POV) doesn't care about the current apartment model.
So, is there an idiomatic way to write COM code that operates on the 'same' object, but can be called from both STA and MTA threads?
发布评论
评论(1)
将 COM 对象接口放入全局接口表并让 GIT 为您处理编组工作。当任何线程请求 COM 接口时,GIT 会检查调用单元并相应地提供直接指针或合适的代理。您的代码不会知道其中的差异(或关心),只需根据需要正常使用返回的接口即可。
MSDN 上对此进行了记录:
跨公寓访问接口
Put the COM object interface into the Global Interface Table and let the GIT handle the marshalling for you. When any thread requests the COM interface, the GIT checks the calling apartment and will provide a direct pointer or a suitable proxy accordingly. Your code won't know the difference (or care), just use the returned interface normally as needed.
This is documented on MSDN:
Accessing Interfaces Across Apartments