c# - 在 C++ dll 中使用 COM 对象

标签 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() 函数是否正确,或者我应该使用带有 COINIT_MULTITHREADED 参数的 CoInitializeEx() 函数吗? 或者我做错了什么? (我通过命令“reg_asm.exe B.dll B.tlb/codebase”注册了B.dll)

抱歉我的英语不好。

谢谢。

最佳答案

您应该在该线程上的任何 COM 事件之前和之后使用 CoInitialize[Ex]/CoUninitialize,并且您可以在 CoInitialize 之间进行选择和具有特定参数的 CoInitializeEx 取决于您更喜欢线程的 STA 模式还是 MTA 模式。

话虽如此,你的初始化:

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

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

  • 如果您接受 COM 单线程单元模型并且不在线程之间传递获得的指针,那么看起来不错
  • 最好将 CoInitializeCoUninitialize 调用移出构造函数并将其与线程代码相关联
  • 一定要检查返回值以检测故障,尤其是。尝试在已经进行 COM 初始化的线程上初始化不匹配的单元
  • 您缺少的部分是您必须在 CoUninitialize 调用之前关闭所有 COM 事件,包括释放您的 MyComObject 指针。

关于c# - 在 C++ dll 中使用 COM 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28424020/

相关文章:

c# - 在 linq 中使用不同的选择进行分组

c# - Powershell 二进制模块 : Dynamic tab completion for Cmdlet parameter values

c++ - list<string> test() 和 list<string> test 区别?

c++ - C++ 异构集合调用派生类函数

c# - WPF:应用程序空闲时间

c# - 带条件间距的 string.format 效率

c++ - 在 QDialog::exec() 期间使用 QThreads 执行 QWidget::grab()

c++ - 在优化校准中绘制图像

c++ - 搜索 winapi 函数

c# - 当我将鼠标悬停在组合框项目上时引发事件