我有一个在后台线程中创建的ADO Recordset
对象:
var
conn: TADOConnection;
rs: _Recordset;
begin
conn := CreateDatabaseConnection();
rs := conn.Execute(CommandText, cmdText, []);
conn.Free;
//Give the recordset to the UI thread
//Don't forget to add a reference before we stuff it into a 32-bit variable
rs._AddRef();
PostMessage(hwndUIThreadWindow, WM_HeresTheRecordsetYouAskedFor, WPARAM(rs), 0);
end;
然后将Recordset
传递给我的" main" 主题:
procedure ExecuteComplete(var msg: TMessage); message WM_HeresTheRecordsetYouAskedFor;
var
rs: _Recordset;
begin
rs := _Recordset(msg.wParam);
//don't forget to remove the manually added reference
rs._Release();
ShowMessage(rs.Fields['TheTimeIs'].Value);
end;
我也可以做到:
var
global_Recordset: _Recordset;
var
conn: TADOConnection;
begin
conn := CreateDatabaseConnection();
global_Recordset := conn.Execute(CommandText, cmdText, []);
conn.Free;
end;
无论哪种方式,没有创建COM对象的线程现在都在使用它。来自主主题:
global_Recordset .Fields['TheTimeIs'].Value;
COM禁止访问未创建对象的公寓(在本例中为 threads )中的COM对象。
在公寓边界的进程内 COM对象接口中编组正确的方法是什么?
答案 0 :(得分:4)
在公寓之间传递COM对象的正确方法是编组接口指针,这可以通过两种不同的方式之一完成:
让工作线程调用CoMarshalInterThreadInterfaceInStream()
函数并将生成的IStream
指针传递给UI线程,然后调用CoGetInterfaceAndReleaseStream()
函数。
使用IGlobalInterfaceTable
界面。让工作线程创建接口并调用其RegisterInterfaceInGlobal()
方法并将生成的cookie传递给UI线程,然后创建接口并调用其GetInterfaceFromGlobal()
和RevokeInterfaceFromGlobal()
方法。