Почему QueryInterface () завершится ошибкой, если интерфейс обязательно реализован и имеет встроенный маршаллер в Windows?
У меня есть следующие настройки. Там's COM-сервер, который установлен в COM + (для запуска в отдельном процессе) и имеет следующее определение интерфейса:
[object, uuid("InterfaceIdHere"), nonextensible, oleautomation, hidden]
interface IMyInterface : IUnknown {
HRESULT MyMethod( [in] IUnknown* param );
};
Звонящий звонит так:
HRESULT callComObject(IStream* stream)
{
return comObject->MyMethod(stream);
}
Обратите внимание, что здесьIStream*
косвенно повышен доIUnknown*
, Это сделано потому, что объявление параметра типаIStream*
в IDL вызвало некоторые проблемы, которые я могуне помню сейчас. Во всяком случае этовсегда действительныйIStream*
это передается вместо.IUnknown*
На стороне COM-сервера есть такая реализация:MyMethod()
STDMETHODIMP CServer::MyMethod(IUnknown* param)
{
if(param == 0) {
return E_INVALIDARG;
}
ATL::CComQIPtr stream(param);
if(stream == 0) {
return E_INVALIDARG;// control passes HERE
}
// whatever
}
Так что яIStream*
перешел вcallComObject()
на стороне клиента, которая неявно подталкивается кIUnknown*
и последний передается маршаллеру СОМ. МаршаллIUnknown*
достигает сервера в другом процессе и тамIUnknown*
получается и тогдасQueryInterface()
позвонить маршалуIStream*
от того же объекта иQueryInterface()
выходит из строя.
Это выглядит безумно, потому что сортировкаIStream*
должен просто работать всегда - тамМаршаллер для этого интерфейса предварительно установлен в Windows.
Почему это может не сработать и как мне найти причину?