Неохотно вызывает QueryInterface через RPC - PullRequest
1 голос
/ 16 мая 2011

В моем приложении я создаю объект A, который создает объект B, оба через CreateInstance. Оба объекта должны жить в одном и том же процессе.

Теперь я вижу, что объект B, когда его спрашивают об определенном интерфейсе, возвращает E_NOINTERFACE, хотя я определил его в COM_MAP:

class B:
{
    // ....
BEGIN_COM_MAP(B)
    COM_INTERFACE_ENTRY(IB)
    COM_INTERFACE_ENTRY(IDispatch)
    COM_INTERFACE_ENTRY(IXXX) // the interface I'm interested in
END_COM_MAP()
    // .....
};

И код А:

#define FORWARD_ERROR( expr ) { hr=expr; if( !SUCCEEDED( hr ) ) return hr;}
IBPtr b;
FORWARD_ERROR( b.CreateInstance( __uuidof( B ), 0, CLSCTX_INPROC_SERVER ) );

IXXXPtr x;
HRESULT hrIf = b.QueryInterface( __uuidof( IXXX ), x );
// ===> now x is NULL, and hrIf contains E_NOINTERFACE

Когда я отлаживаю это и устанавливаю точку останова в COM_MAP, я не вижу свой исходный код в нижнем фрейме, но некоторые файлы ole32.dll CRpcThread::WorkerLoop.

Понятия не имею, как я указал, что QueryInterface следует вызывать через OLE и RPC. Есть идеи?

Ответы [ 2 ]

1 голос
/ 16 мая 2011

По твоему описанию это было определенно озвучка в .Маршаллинг выполняется путем туннелирования вызовов через RPC, поэтому он выглядит довольно странно, но именно так это и делается в Windows.

Поток потребителя, вероятно, называется CoInitializeEx() с COINIT_APARTMENTTHREADED.Поскольку создаваемый объект был помечен как Free, он не мог быть создан в квартире вызывающего абонента (см. это очень хорошее объяснение по квартирам ).Вместо этого COM попытался включить маршаллинг, и у вас, вероятно, не было ничего, чтобы облегчить маршаллинг , и в таких случаях CoCreateInstance() возвращает E_NOINTERFACE, потому что внутренние рабочие процессы COM запрашивают набор интерфейсов, которые он использовал бымаршалинг и после того, как все эти запросы потерпят неудачу, он заканчивается на E_NOINTERFACE и возвращает его, что, конечно, вам совсем не удобно.

Затем вы изменили с Free на Both, что означает "Apartment из Free по усмотрению COM" COM официально разрешено помещать объект в ту же квартиру, что и вызывающая сторона, и не требуется сортировка, поэтому вы не видите эту странную ошибкукод больше.

1 голос
/ 16 мая 2011

Модель потока для класса B была «Свободна», когда я создавал объект из многопоточного контекста. Переключение B на «Оба» решило проблему.

...