gpt4 book ai didi

windows - 为什么我不需要在 COM 线程内创建的线程中调用 CoInitialize?

转载 作者:可可西里 更新时间:2023-11-01 14:41:21 27 4
gpt4 key购买 nike

为了学习多线程,我在 COM 线程 (TRemoteDataModule) 中创建了一个线程。

这是我的组件工厂:

TComponentFactory.Create(ComServer, TServerConn2, Class_ServerConn2, ciMultiInstance, tmApartment);

在线程内,我不需要调用 CoInitialize 来使用 TADOQuery.Create.Open... .Exec

我读到 I need to initialize the COM library on a thread before you call any of the library functions except CoGetMalloc, to get a pointer to the standard allocator, and the memory allocation functions.

但在这种情况下,没有 CoInitialize 并没有给我带来任何麻烦。
这与线程模型有关吗?我在哪里可以找到这个主题的解释?

更新:

当我说 INSIDE 时,它意味着在 COM 方法上下文中:

interface
type
TWorker = class(TThread);

TServerConn2 = class(TRemoteDataModule, IServerConn2)
public
procedure Method(); safecall;
end;


implementation
procedure TServerConn2.Method();
var W: TWorker;
begin
W := TWorkerTread.Create(Self);
end;

更新 2:

用于连接到数据库的TADOConnection 当前正在COM 线程上下文中创建(TThread.Create 构造函数)。尽管 TADOConnection.OpenTADOQuery.Create/.Open 都在 TThread.Execute 中执行。

更新 3 - Simulacrum

接口(interface):

type
TServerConn2 = class;

TWorker = class(TThread)
private
FDB: TADOConnection;
FOwner: TServerConn2;
protected
procedure Execute; override;
public
constructor Create(Owner: TServerConn2);
destructor Destroy; override;
end;

TServerConn2 = class(TRemoteDataModule, IServerConn2)
ADOConnection1: TADOConnection;
procedure RemoteDataModuleCreate(Sender: TObject);
private
{ Private declarations }
protected
class procedure UpdateRegistry(Register: Boolean; const ClassID, ProgID: string); override;
procedure CheckException; safecall;
public
User, Pswd, Str: String;
Ok: Boolean;
end;

实现:

class procedure TServerConn2.UpdateRegistry(Register: Boolean; const ClassID, ProgID: string);
begin
if Register then
begin
inherited UpdateRegistry(Register, ClassID, ProgID);
EnableSocketTransport(ClassID);
EnableWebTransport(ClassID);
end else
begin
DisableSocketTransport(ClassID);
DisableWebTransport(ClassID);
inherited UpdateRegistry(Register, ClassID, ProgID);
end;
end;

{ TWorker }

constructor TWorker.Create(Owner: TServerConn2);
begin
inherited Create(False);
FreeOnTerminate := True;
FDB := TADOConnection.Create(nil);
FOwner := Owner;
end;

destructor TWorker.Destroy;
begin
FDB.Free;
FOwner.Ok := True;
inherited;
end;

procedure TWorker.Execute;
var Qry: TADOQuery;
begin
FDB.LoginPrompt := False;
FDB.ConnectionString := FOwner.Str;
FDB.Open(FOwner.User, FOwner.Pswd);

Qry := TADOQuery.Create(nil);
try
Qry.Connection := FDB;
Qry.LockType := ltReadOnly;
Qry.SQL.Text := 'SELECT TOP 1 * FROM MyTable';
Qry.Open;
finally
Qry.Free;
end;
end;

procedure TServerConn2.CheckException;
var W: TWorker;
begin
W := TWorker.Create(Self);
while not Ok do Sleep(100);
end;

procedure TServerConn2.RemoteDataModuleCreate(Sender: TObject);
begin
User := 'user';
Pswd := 'pass';
Str := ADOConnection1.ConnectionString;
end;

initialization
TComponentFactory.Create(ComServer, TServerConn2,
Class_ServerConn2, ciMultiInstance, tmApartment);
end.

更新 4

错误应该发生在这里:

function CreateADOObject(const ClassID: TGUID): IUnknown;
var
Status: HResult;
FPUControlWord: Word;
begin
asm
FNSTCW FPUControlWord
end;
Status := CoCreateInstance(ClassID, nil, CLSCTX_INPROC_SERVER or
CLSCTX_LOCAL_SERVER, IUnknown, Result);
asm
FNCLEX
FLDCW FPUControlWord
end;
if (Status = REGDB_E_CLASSNOTREG) then
raise Exception.CreateRes(@SADOCreateError) else
OleCheck(Status);
end;

通过某种方式(可能是因为 TComponentFactory?)CoCreateInstance 识别出 TWorkerTServerConn2 处于相同的上下文中> 并且不报错?

最佳答案

以下任何一项或两项都可能适用:

  1. 在未使用 COM 初始化的线程上,所有现有接口(interface)指针都会继续工作,直到您进行 COM API 调用或以其他方式要求 COM 编码,然后无法检测到未初始化的线程。也就是说,你说“没有给我带来任何麻烦”实际上可能还为时过早。

  2. If any thread in the process calls Co­Initialize­[Ex] with the COINIT_MULTI­THREADED flag, then that not only initializes the current thread as a member of the multi-threaded apartment, but it also says, "Any thread which has never called Co­Initialize­[Ex] is also part of the multi-threaded apartment." - 所谓的 impicit MTA 东西

关于windows - 为什么我不需要在 COM 线程内创建的线程中调用 CoInitialize?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18147048/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com