我可以检查是不是已调用 CoInitialize 吗?

Posted

技术标签:

【中文标题】我可以检查是不是已调用 CoInitialize 吗?【英文标题】:Can I check to see if CoInitialize has been called or not?我可以检查是否已调用 CoInitialize 吗? 【发布时间】:2013-01-10 15:32:28 【问题描述】:

在具有 ADO 数据库连接的多线程环境中,我想知道是否调用了 CoInitialize。我该如何检查这个?

【问题讨论】:

@KenWhite - 不要忘记线程的构造函数是在不同线程的上下文中调用的,通常也是析构函数。所以这些调用将在错误的上下文中调用。 @Serg:是的,你是对的。应该在线程本身的ExecuteOnTerminate 中调用,或者在Execute 中调用try..finally 块。 是的,这个检查将在我需要检查的线程内。 为什么你不能跟踪你是否初始化了 com?当然,您应该能够管理这些细节。 注意:新的持续问题询问如何识别CoInitialize 中的多少级别已被调用:***.com/questions/14543496/… 【参考方案1】:

通常您不应该进行此检查,只需致电 CoInitialize/CoUnInitialize 对。你仍然可以这样做:

function IsCoInitialized: Boolean;
var
  HR: HResult;

begin
  HR:= CoInitialize(nil);
  Result:= (HR and $80000000 = 0) and (HR <> S_OK);
  if (HR and $80000000 = 0) then CoUnInitialize;
end;

如果你在一个线程中多次调用CoInitialize 没有问题。第一次调用应返回S_OK,所有后续调用应返回S_FALSE。所有这些调用都被认为是成功的,应该通过CoUnInitialize 调用配对。如果您在一个线程中调用了 n 次 CoInitialize,则只有最后 n 次 CoUnInitialize 调用会关闭 COM。

【讨论】:

@Serg,现在我正在查看在我的 Delphi 2009 Windows.pas 单元中定义的 CO_E_ALREADYINITIALIZED = HRESULT($800401F1) 常量,并带有注释 CoInitialize has already been called. 并想知道这个常量是什么。您以前见过或遇到过这种情况吗?这不是返回后续CoInitialize 函数调用的原因吗(现在无法验证)? @TLama - 我猜CO_E_ALREADYINITIALIZED 永远不会被CoInitialize 返回,它特定于其他 COM 函数。 所以你的意思是,如果我调用CoInitialize()n 次,并调用CoUninitialize()n-1 次,那么COM 仍然会为那个线程打开?

以上是关于我可以检查是不是已调用 CoInitialize 吗?的主要内容,如果未能解决你的问题,请参考以下文章

Python 方法是不是可以检查它是不是已从自身内部调用?

如何实现一个系统调用,它可以在不进入内核日志的情况下检查自身是不是已成功执行?

Qt-不调用CoInitialize-实现SDL多线程运行

Qt-不调用CoInitialize-实现SDL多线程运行

Coinitialize ex 在 JNI 程序存根中的 WMI 调用中失败

多线程调用COM组件的体会(CoInitialize)(转)