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

标签 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 对象将在每次函数调用时实例化,并且此变体按预期工作(每个线程现在都有自己的单元和对象的实例),但恐怕这不是最佳解决方案,因为实例化是昂贵的操作。

能否以某种方式做得更好?

最佳答案

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

目前,您正在将线程初始化为单线程单元,这意味着在该线程上创建的任何对象都只会在该线程上执行它们的函数。如果您尝试从不同的线程使用这些对象之一,调用将编码到创建它们的线程。

如果 COM 需要将函数调用编码到另一个线程,它会通过 Windows 的消息系统来完成。如果线程不发送消息,则永远不会调用该函数;这很可能是您正在发生的事情,也是您看到没有执行任何操作的原因。

如果在调用 CoInitializeEx 时使用 COINIT_MULTITHREADED 而不是 COINIT_APARTMENTTHREADED 将线程初始化为多线程单元,它将允许对象由该线程创建(即您的 order)以用于任何其他线程。

关于c++ - COM对象在多线程客户端中的初始化和实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19612148/

相关文章:

c++ - 共享指针线程安全是零成本吗?

c++ - #import 导致 HRESULT 0x80040154 "Not registered class"

android - 在 android Lame 中找不到 void com.example 的实现

c++ - 从 Qt 上的 UNIX 域套接字 (QLocalSocket) 读取

c++ - Magick++ 模糊蒙版

c++ - 如何开始 bho(浏览器帮助对象)编程

string - 我使用哪种宽字符串结构? CString vs wstring

c++ - 这段代码是否应该调用复制或移动构造函数

javascript - 如何让 Webworker 真正响应以及为什么 setTimeout() 不起作用

windows - 跨线程的数值差异(cygwin 上的 openMP)