跨DLL调用CoInitialize/CoUninitialize的适当位置是什么?

3
我正在实现一个包含共享ADO连接的DLL,使用TADOConnectionConnectionObject属性,并将其跨越DLL边界传递到其他TADOConnection实例中。我需要确保初始化COM,因此需要调用CoInitialize / CoUninitialize。目前它在VCL主线程的上下文中,但可能在另一个线程的其他地方,这当然需要自己的COM实例。我目前没有实现多线程。
在哪里调用这些方法才是合适的?是在DLL内部(加载/卸载期间)、DLL外部(调用进程)还是两者都要?考虑到只有一个线程,不应该在原始进程中只调用一次吗?
我假设原始调用线程应该独自负责这个,因为COM在线程的上下文中运行。当然,在两侧都调用它们不会有任何问题,但这也会创建多个COM实例。
长话短说...在这种情况下,是“安全保险”吗?还是只保留一个COM实例很重要?

在我打字的过程中,我基本上回答了自己的问题,我只是需要确认我理解的是否正确。 - Jerry Dodge
当然,在两侧调用它们不会有任何问题,但这也会创建多个COM实例。- 但是这会有影响。您应该只在自己拥有的线程上CoInitialize - acelent
1个回答

7

您不应该在DLL中这样做。将其作为DLL和主机之间的契约的一部分,使主机负责初始化COM。

DLL不能期望初始化COM,因为主机可能已经完成了此操作。而且要使用不同的线程模型。一旦初始化了COM,那么未来尝试进行初始化的操作将失败,如果它们尝试更改线程模式。

因此,请不要在DLL中初始化COM。要求主机这样做。


是的,我忘记了不同的线程模型 - 这肯定会在共享连接的两个实现中引起问题。 - Jerry Dodge
这并不是关于DLL代码的问题,而是关于线程所有权的问题。如果您启动了线程,则可能(并且可能应该)初始化COM。如果您没有这样做,则最多可以要求调用者以特定方式初始化COM(例如单线程、多线程、OLE)。 - acelent

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接