multithreading - 关于COM多线程和STA/MTA的问题

标签 multithreading user-interface com sta mta

嗨,我是 COM 初学者。我想在 STA 和 MTA 模式下测试 COM dll。我的第一个问题是:COM 对象是否可能同时支持 STA 和 MTA?

现在我想象下面的 STA 代码片段:

// this is the main thread
m_IFoo;
CoInitializeEx(STA); // initialize COM in main thread
CreateInstance(m_IFoo);
m_IFoo->Bar();

CreateThread(ThreadA);
// start ThreadA

// this is secondary thread
ThreadA()
{
    CoInitializeEx(STA);
    m_IFoo->Buz(); // call m_IFoo's method directly
}

这段代码可以工作吗?我是否遗漏了任何基本的东西?我知道主线程需要一个窗口消息循环来执行来自其他线程的调用。我需要做些什么吗?

现在我继续测试 MTA。如果我只是将上面代码中的“STA”替换为“MTA”,可以吗?

另一个问题是:由于带有GUI的线程必须是STA,所以我无法在GUI线程中初始化和测试MTA?

提前致谢,并为我对 COM 和线程的幼稚感到抱歉。

最佳答案

您的代码不是合法的 COM,因为您将指针直接从一个 STA 传递到另一个 STA,而 COM 不允许这样做。

在COM中,接口(interface)指针具有“公寓亲和性”,它们只能在公寓内使用。要将指针从一个 STA 传递到另一个 STA,或者在 STA 和 MTA 之间传递,您必须将指针“编码”到一个安全的表示形式,然后由接收线程取消编码。

最简单的方法是使用 Global Interface Table ;您在一个线程中向其注册接口(interface)并返回一个 DWORD,然后在另一个线程中使用它来获取另一个线程可以使用的接口(interface)版本。

如果两个线程都是 MTA,则可以避免这样做。虽然 STA 是每个线程一个 - 每个 STA 线程都有自己的公寓 - MTA 由所有 MTA 线程共享。这意味着 MTA 线程可以在它们之间自由传递 COM 指针。 (但如果将指针传递给 STA 线程或从 STA 线程传递指针,它们仍然需要编码(marshal)。)

一般来说,您不会在 STA 或 MTA 之间更改代码,通常一开始就决定一次。如果线程有UI,那么它需要消息循环,并且通常是STA。如果没有 UI,您可能会决定使用 MTA。但是,一旦您做出决定并编写代码,以后就很少会更改为另一个,因为选择一个或另一个具有影响代码的不同要求和假设;从 STA 更改为 MTA,反之亦然,您必须仔细检查代码,看看是否需要更改指针分配等内容。

关于multithreading - 关于COM多线程和STA/MTA的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6253692/

相关文章:

c - 重复使用相同的线程

multithreading - 并发 Haskell 异常

java - 刷新 JCalendar 中的 RangeEvaluator

c# - 在屏幕外(或隐藏)渲染网络浏览器控件

c - 在没有 VirtualBox 的情况下使用 VirtualBox SDK

winapi - CopyItems 和 MoveItems 在 windows-7 64 位上崩溃

java - 使用JAVA Spring同步rest服务

java - 这里需要用到ThreadLocal吗?

c# - UI 不更新 ExpandoObject 列表

java - GUI Java 程序 - Paint 程序