通过阅读本网站上的几个答案,我了解到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)初始化方面的麻烦?
答案 0 :(得分:7)
这很简单。记录您库的任何消费者必须初始化COM。这样做是完全可敬和平常的。将这样的要求放在图书馆的消费者身上真的没什么可担心的。如果他们不能做他们所要求的,那就是他们的问题。正如您所指出的,线程的创建者必须负责初始化COM,因此您没有可行的替代方案。