使用C++dll中的COM对象

Using COM Object in C++ dll

本文关键字:对象 COM 中的 C++dll 使用      更新时间:2023-10-16

我正在编写一个Win32 C++DLL,该DLL使用C#中生成的COM对象(B.DLL)。这个dll(A.dll)提供CMyComObject类,该类创建COM对象并访问它。这是我的密码。

void CMyComObject::CMyComObject() 
{    
  HRESULT result = CoInitialize(NULL);
  ...
  result = CoCreateInstance(CLSID_COMDLL, NULL, CLSCTX_INPROC_SERVER,     IID_COMDLL, reinterpret_cast<void**>(&MyComObject));
}
void CMyComObject::~CMyComObject() 
{
  ..
  CoUninitialize();
  ..
}

然后,这里有一个客户端程序,它加载a.dll并访问COM对象。该程序创建多个线程,这些线程同时加载A.dll并创建COM对象。

在这种情况下,使用CoInitialize()函数正确吗?还是应该将CoInitializeEx()函数与COINIT_MULTITHREADED参数一起使用?或者我做错了什么?(我通过命令"reg_asm.exe B.dll B.tlb/codebase"注册了B.dll)

抱歉我英语不好。

谢谢。

您应该在该线程上的任何COM活动之前和之后使用CoInitialize[Ex]/CoUninitialize,并且您在CoInitializeCoInitializeEx之间选择特定参数取决于您的线程是喜欢STA模式还是MTA模式。

话虽如此,您的初始化:

  1. 不取决于COM对象本身是否创建任何线程
  2. 不依赖于可能具有其他COM活动的应用程序的其他部分,包括相同COM类的类似实例化
  3. 完全取决于您在有问题的线程上的COM活动
  4. 通常不会发生在类构造函数中;典型的是在windows消息泵之前或在线程过程的一开始就进行与顶级线程代码相关联的COM初始化;将它放入构造函数是一种容易发生冲突的方法,例如与另一个初始化(特别是使用不同的公寓模型)或过早取消初始化

再次总结,您的初始化:

  • 如果您对COM单线程单元模型满意,并且不在线程之间传递所获得的指针,则看起来不错
  • 最好将CoInitializeCoUninitialize调用移出构造函数,并将其与线程代码关联起来
  • 请务必检查返回值以检测失败,特别是尝试在已经进行COM初始化的线程上初始化不匹配的单元
  • 缺少的部分是必须在CoUninitialize调用之前关闭所有COM活动,包括释放MyComObject指针