如何从库的角度处理COM(un)初始化?

时间:2017-01-06 03:26:59

标签: delphi com

通过阅读本网站上的几个答案,我了解到CoInitialize(Ex) should be called by the creator of a thread。然后,在该线程中运行的任何代码都可以使用COM。如果该代码本身恰好调用CoInitialize(Ex),那将是无害的,因为它没有任何效果。它不应该调用CoUninitialize - 这也应该由线程的创建者完成 - 但如果它检查CoInitialize(Ex)的{​​已保存的]结果S_FALSE它就不会被激活}。如果创建者不负责执行初始化,则线程处于" mercy"该代码选择一个合适的线程模型,从那时起就不会发生变化。

所有这些对于编写和使用库有什么影响?

当所有代码都是您自己的代码,并且您拥有一个小团队时,可以很好地组织COM(un)初始化调用。但是,对于图书馆,用户不应该知道他们如何做他们做的事情,例如COM参与其中。我不喜欢在文档中有什么可以在代码中处理。此外,除非涉及VCL代码,否则不应假设库代码将运行在哪个线程中。

我检查过的大多数开源库都会在CoInitialize(Ex)部分调用initialization,在CoUninitialize部分调用finalization,甚至不检查初始化是否成功。有些人会调用InitProc,但有些人会先检查IsLibrary

他们真的应该做什么?如果我自己写一个单元,我希望任何人都可以在没有多少考虑的情况下使用该怎么办?在线程中包装触及COM的所有内容并让该线程执行自己的COM(un)初始化?

与那些开源单位一样,天真真的有多糟糕?在VCL应用程序中使用它们时,它们的COM(un)初始化将始终在主线程上运行,该主线程已经具有performed first by Forms.TApplication.Create。这会使单位的电话无辜而无用吗?如果在.dpr之前Forms中列出了任何单位,该怎么办?那些非VCL应用程序或DLL的呢?在纠正之前我不应该使用这些装置吗?我是否应该以某种方式防范他们可能会尝试做什么,通过预防性地初始化COM?

这是一个相当复杂的问题,但这一切都归结为:如何(容易)避免COM(un)初始化方面的麻烦?

1 个答案:

答案 0 :(得分:7)

这很简单。记录您库的任何消费者必须初始化COM。这样做是完全可敬和平常的。将这样的要求放在图书馆的消费者身上真的没什么可担心的。如果他们不能做他们所​​要求的,那就是他们的问题。正如您所指出的,线程的创建者必须负责初始化COM,因此您没有可行的替代方案。