在C ++ DLL中使用COM对象

时间:2015-02-10 04:17:49

标签: c# c++ winapi com

我正在编写一个Win32 C ++ 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)

抱歉我的英语不好。

感谢。

1 个答案:

答案 0 :(得分:1)

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

话虽如此,你的初始化:

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

    • 看起来很好,如果你对COM单线程公寓模型没问题,并且你没有在线程之间传递获得的指针
    • 最好将CoInitializeCoUninitialize调用移出构造函数并将其与线程代码相关联
    • 务必检查返回值以检测故障,尤其是尝试在已经具有COM初始化的线程上初始化不匹配的单元
    • 您遗失的部分是您必须在调用CoUninitialize之前关闭所有COM活动,包括释放MyComObject指针。