2015-02-10 90 views
0

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

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)

对不起,我的英语很差。

谢谢。

+0

在这个问题中提供的信息刚好足以给出一个危险*不准确的答案,并且可能*正确的答案。您打算如何访问这些COM对象以及他们的注册声明是什么(公寓,免费等)也是等式的一部分。而且,fyi CoInit不是一件物品;它的每个线程*。原因和方法太牵涉到这里的评论。我强烈建议一本关于COM编程的好书/教程,其中有许多*。 – WhozCraig 2015-02-10 05:32:00

回答

1

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

说了这么多,你的初始化:

  1. 不依赖于COM对象本身是否创建的所有线程
  2. 不依赖于应用程序的其他部分可能具有其它COM活动,包括类似的实例相同的COM类
  3. 完全取决于你在所讨论线程上的COM活动
  4. 通常不会在类构造函数中发生;通常将COM初始化与顶级线程代码相关联,例如在windows消息泵之前或在线程过程的开始时;把它放入构造函数是一种容易碰撞的简单方法,例如与另一个初始化(尤其是使用不同的公寓模式)或太早的未初始化。

再次总结这一切,你的初始化:

  • 看起来,如果你是使用COM单线程单元模型好啊好啊,你不及格线之间获得指针
  • 你会更好关闭移动CoInitializeCoUninitialize调出构造函数并将其与线程代码关联
  • 请确保检查返回的值以检测故障,尝试在已初始化COM初始化的线程上初始化不匹配的公寓。
  • 您缺少的部分是您必须在呼叫CoUninitialize之前关闭所有COM活动,包括释放您的MyComObject指针。