阅读了本站上的几个答案,我了解到
我检查过的大多数开源库在初始化部分调用
他们真正应该做什么?如果我自己编写一个单元,希望任何人都能够轻松使用,该怎么办?将所有涉及COM的内容包装在一个线程中,并使该线程执行其自己的COM(取消)初始化。
当使用那些开源单元在VCL应用程序中时,对于那些关于它的天真态度到底有多糟糕呢?它们的COM(un)初始化总是在主线程上运行,该线程已经由
这是一个相当复杂的问题,但归根结底就是:如何(使其易于)避免与COM(未)初始化相关的麻烦?
CoInitialize(Ex)
应该由线程的创建者调用。然后,运行在该线程中的任何代码都可以使用COM。如果该代码恰好通过自身调用CoInitialize(Ex)
,那么这将是无害的,因为它不会产生任何影响。它不应该调用CoUninitialize
- 这也应该由线程的创建者完成 - 但如果它检查CoInitialize(Ex)
的(保存的)结果,即S_FALSE
,则它不会这样做。如果创建者不承担执行初始化的责任,则线程将处于该代码的“掌控”下,以选择适当的线程模型,从此以后将无法更改。
所有这些对编写和使用库有什么影响?
当所有代码都是您自己的,而且您有一个小团队时,很容易组织好COM(取消)初始化调用。但是,对于库,用户不应该需要知道它们如何执行操作,例如涉及COM。我讨厌在文档中写可以在代码中处理的内容。除非涉及VCL代码,否则不应做出关于库代码将在哪个线程中运行的任何假设。我检查过的大多数开源库在初始化部分调用
CoInitialize(Ex)
,并在终止部分调用CoUninitialize
,甚至经常没有检查初始化是否成功。一些调用InitProc
,但有些先检查IsLibrary
。他们真正应该做什么?如果我自己编写一个单元,希望任何人都能够轻松使用,该怎么办?将所有涉及COM的内容包装在一个线程中,并使该线程执行其自己的COM(取消)初始化。
当使用那些开源单元在VCL应用程序中时,对于那些关于它的天真态度到底有多糟糕呢?它们的COM(un)初始化总是在主线程上运行,该线程已经由
Forms.TApplication.Create
执行。这是否使得单元中的调用无辜但无用?如果任何一个单元在.dpr
中排在Forms
之前,会怎么样?非VCL应用程序或DLL呢?我在纠正它们之前不应该使用这样的单元吗?我是否应该通过始终预先初始化COM来防范它们可能尝试做的事情?这是一个相当复杂的问题,但归根结底就是:如何(使其易于)避免与COM(未)初始化相关的麻烦?