【问题标题】:What's the appropriate place to call CoInitialize/CoUninitialize across DLL's?跨 DLL 调用 CoInitialize/CoUninitialize 的合适位置是什么?
【发布时间】:2015-07-13 06:28:42
【问题描述】:

我正在实现一个包含a shared ADO Connection 的DLL,方法是使用TADOConnectionConnectionObject 属性并将其跨DLL 边界传递到TADOConnection 的其他实例。我需要确保 COM 已初始化,因此我需要调用 CoInitialize / CoUninitialize。目前它在 VCL 主线程的上下文中,但可能在另一个线程的其他地方,当然是requires its own instance of COM。我目前没有实现多线程。

在哪里合适地调用这些;在 DLL 内部(加载/卸载期间),在 DLL 外部(调用进程),还是两者兼而有之?考虑到只有一个线程,在原进程中不应该只在DLL外一次吗?

我假设最初的调用线程应该对此单独负责,因为 COM 在线程的上下文中运行。当然在双方都调用它们应该不会有任何伤害,但是它也会创建多个 COM 实例。

长话短说......在这种情况下“安全是安全的”吗?还是只保留一个 COM 实例很重要?

【问题讨论】:

  • 我基本上是在打字的时候回答了我自己的问题,我只需要确认我理解的内容。
  • 当然,在双方都调用它们不应该有任何伤害,但是它也会创建多个 COM 实例。 - 但它会伤害。你应该只 CoInitialize 一个你拥有的线程。

标签: delphi dll com ado


【解决方案1】:

您不应该在 DLL 中执行此操作。使其成为 DLL 与主机之间的契约的一部分,主机负责初始化 COM。

不能期望 DLL 初始化 COM,因为主机可能已经这样做了。并使用不同的线程模型。一旦 COM 被初始化,如果他们尝试更改线程模式,未来的初始化尝试将失败。

所以,不要在 DLL 中初始化 COM。要求主人这样做。

【讨论】:

  • 是的,不同的线程模型让我忘记了——这肯定会在共享连接的两种实现中造成问题。
  • 这与 DLL 代码无关,它与线程所有权有关。如果您启动线程,您可能(并且可能应该)初始化 COM。如果你不这样做,你最多可能要求调用者以特定方式初始化 COM(例如单线程、多线程、OLE)。
猜你喜欢
  • 2013-10-26
  • 1970-01-01
  • 1970-01-01
  • 2018-04-17
  • 2011-04-11
  • 2019-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多