我正在为一个软件编写插件。该软件调用
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/