我能否检查是否已调用CoInitialize函数?

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

2
@KenWhite - 别忘了线程的构造函数是在不同的线程上下文中调用的,析构函数通常也是如此。因此,这些调用将在错误的上下文中被调用。 - kludg
1
@Serg:没错,应该在线程的ExecuteOnTerminate中调用,或者在Execute中使用try..finally块。 - Ken White
是的,这个检查将在我需要检查的线程内部进行。 - Jerry Dodge
为什么你不能跟踪是否初始化了com?你应该能够管理这些细节。 - David Heffernan
实际上我已经是了,这只是为了调试目的。 - Jerry Dodge
1
注意:有一个新的继续提问,询问如何识别已调用了多少层CoInitialize:https://dev59.com/um3Xa4cB1Zd3GeqPhrbz - Jerry Dodge
1个回答

15

通常情况下,您不应该进行此检查,而是直接调用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调用成对出现。如果在线程中调用了CoInitialize n 次,则只有最后第 n 个CoUnInitialize调用会关闭COM。


2
@Serg,现在我正在查看我的Delphi 2009 Windows.pas单元中定义的CO_E_ALREADYINITIALIZED = HRESULT($800401F1)常量,并且想知道这个常量是用来干什么的。它的注释是“CoInitialize已经被调用了。”你见过或遇到过这个吗?这不是返回后续的CoInitialize函数调用的内容吗(现在无法验证)? - TLama
3
我猜测CO_E_ALREADYINITIALIZED永远不会被CoInitialize返回,它是特定于其他COM函数的。 - kludg
1
那么你的意思是,如果我调用了 CoInitialize() n 次,并且调用了 CoUninitialize() n-1 次,那么 COM 对于该线程仍然是打开状态? - kakyo

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