多线程客户端中COM对象的初始化和实例化

时间:2013-10-26 21:35:19

标签: c++ multithreading com initialization

我正在为一个软件编写插件。该软件调用

 void Init() {...}

加载并具有多线程功能:程序可以运行多个线程,可以同时从我的插件调用自定义函数。

在我的插件中,我正在使用COM对象,我按照以下方式初始化:

void Init() { // "Global" initializaton
    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
    position.CreateInstance(__uuidof(Position));
    order.CreateInstance(__uuidof(Order));
}

接下来我实现了基于插件的功能(例子):

int SendOrder(....) {
    return order.SendOrder(...); // invoke COM object's method
}

问题是这个变种没有按预期工作,所以我将COM对象实例化直接移动到函数体:

int SendOrder(....) {
    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
    order.CreateInstance(__uuidof(Order));

    int ret = order.SendOrder(...);

    CoUnitialize();

    return ret;
}

现在COM对象将在每个函数调用上实例化,并且此变体按预期工作(每个线程现在都有它自己的公寓和对象的实例),但我担心这不是最好的解决方案,因为实例化是昂贵的操作。

这可以以某种方式更好地完成吗?

1 个答案:

答案 0 :(得分:1)

如果您希望能够在多个线程上同时调用COM对象,则应该初始化线程以使用多线程单元而不是单线程单元。

目前,您正在将线程初始化为单线程单元,这意味着在该线程上创建的任何对象将仅在该线程上执行其功能。如果您尝试从其他线程使用其中一个对象,则调用封送到创建它们的线程。

如果COM需要编组一个函数调用另一个线程,它会通过Windows的消息传递系统来完成。如果线程没有泵送它的消息,则永远不会调用该函数;这很可能是你发生的事情,以及为什么你看到没有任何事情被执行。

如果在调用COINIT_MULTITHREADED时使用COINIT_APARTMENTTHREADED而不是CoInitializeEx将线程初始化为多线程公寓,则会允许此线程创建的对象(即您的{{ 1}})用于任何其他线程。

相关问题