2013-06-27 1 views
3

у меня есть ADO Recordset объект, который создается в фоновом потоке:Как передать набор записей ADO (или любой объект COM) через границы потоков?

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 передается на мой «основной» нить:

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 запрещает доступ к COM-объекты из квартир (в данном случае: темы), которые не создают объект.

Что такое правильно способ маршала в в процессе интерфейсов COM объектов через границу квартиры?

+1

Не совсем ответ, но выглядят немного дальше и передать данные, которые вы хотите, а не COM-объект ... – whosrdaddy

+0

@whosrdaddy звучит как хороший ответ мне. –

+0

@whosrdaddy Представьте, что я сохранил свои данные сопряженной переменной. Тот же вопрос. –

ответ

4

Правильный способ передать COM-объект через квартиры маршала указатель интерфейса, который может быть сделан в одном из двух различных способов:

  1. Есть рабочий поток вызова функции CoMarshalInterThreadInterfaceInStream() и передать в результате IStream указатель на поток пользовательского интерфейса, который затем вызывает функцию CoGetInterfaceAndReleaseStream().

  2. Используйте интерфейс IGlobalInterfaceTable. Попросите рабочий поток создать интерфейс и вызвать его метод RegisterInterfaceInGlobal() и передать полученный файл cookie в поток пользовательского интерфейса, который затем создает интерфейс и вызывает его методы GetInterfaceFromGlobal() и RevokeInterfaceFromGlobal().

+0

Добавление примечания, что эти решения работают только для квартир в одном и том же процессе и не могут использоваться в общем случае для маршализации интерфейсов между квартирами. –

 Смежные вопросы

  • Нет связанных вопросов^_^