Форум: "Corba";
Текущий архив: 2006.03.26;
Скачать: [xml.tar.bz2];
ВнизМаршаллинг интерфейса. Найти похожие ветки
← →
Владислав © (2005-05-06 12:30) [0]Здравствуйте.
Вот здесь:
http://www.rsdn.ru/Forum/Message.aspx?mid=1159650&only=1
я задал вопрос. Понятно, что на форуме по Delphi он не совсем уместен, но здесь тоже бывают люди, пишущие на MS VC.
Повторю его содержание:
Здравствуйте.
Проблема в следующем.
COM сервер реализован, как out-of-prosecc сервер (в EXE). В нем объявлен интерфейс:
// IServerList Interface
[
object,
uuid(297481F0-A3D2-43d1-B0DB-9A6C4B007885),
helpstring("IServerList Interface"),
pointer_default(unique)
]
interface IServerList : IUnknown{
[helpstring("method RegisterServer")] HRESULT RegisterServer([in] BSTR ConnStr, [out] LPDBOBJECTID ObjID, [out] IServer ** Server);
[helpstring("method UnregisterServer")] HRESULT UnregisterServer([in] LPDBOBJECTID ObjID);
[helpstring("method EnumServer")] HRESULT EnumServer([out] IEnumServer ** Enum);
};
При попытке вызова метода EnumServer получаю результат "интерфейс не реализован".
Сам интерфейс IEnumServer определен так:
// IEnumServer Interface
[
object,
uuid(D1019908-2CB3-4e71-9649-942750D0ED47),
helpstring("IEnumServer Interface"),
pointer_default(unique)
]
interface IEnumServer : IUnknown{
[helpstring("method Next")] HRESULT Next([in] ULONG celt, [out, size_is(celt), length_is(*pceltFetched)] IServer ** rgelt , [out] ULONG * pceltFetched);
[helpstring("method Skip")] HRESULT Skip([in] ULONG celt);
[helpstring("method Reset")] HRESULT Reset(void);
[helpstring("method Clone")] HRESULT Clone([out] IEnumServer ** ppenum);
};
Класс для интерфейса IEnumServer реализован с помощью шаблонов вот так:
// Declaration of the CEnumServer
typedef _CopyInterface<IServer> CServerCopy;
typedef CComEnum<IEnumServer, &CLSID_EnumServer, IServer *, CServerCopy> CEnumServer;//Class;
Возвращается энумератор так:
STDMETHODIMP CServerList::EnumServer(IEnumServer ** Enum)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr;
CComPtr<IServer> iServer;
CCommonClass<CServer> * cServer = NULL;
// Get pointer to IServer interface
hr = GetInterfaceFromClass<CCommonClass<CServer> , IServer>(&iServer, &cServer);
if (FAILED(hr))
return hr;
IServer * serverIntf = (IServer *)iServer;
// Put pointer to IServer interface to enumerator
hr = CreateEnumerator<CEnumServer, IServer *>(
(IUnknown**)Enum,
&serverIntf,
(&serverIntf + 1),
NULL,
AtlFlagCopy);
return hr;
}
Сервер корректно возвращает энумератор, но до клиента он (энумератор) не доходит.
Ну и еще дополнительная информация... При трассировке сервера, у него запрашиваются интерфейсы IMarshal и IStdMarshalInfo, на которые COM благополучно получает ответ "no implement". При этом proxy/stub зарегестрирована. Впрочем, сам интерфейс IServerList возвращается клиенту благополучно, и его первые два метода работают.
Подскажите пожалуйста, в каком направлении искать ошибку? Что я не так сделал?
← →
Набережных С. © (2005-05-06 14:19) [1]
> у него запрашиваются интерфейсы IMarshal и IStdMarshalInfo
Это стандартное поведение, не обращай внимания, в данном случае значения не имеет.
Судя по тексту ошибки, наиболее вероятно, что проблемы с маршалингом IEnumServer по причине отсутствия Proxy/Stub для него. Посмотри в HCR\Interface, есть ли там этот интерфейс и кто там числится маршалером для него. IServerList и IEnumServer в одном idl описаны?
← →
Владислав © (2005-05-06 17:05) [2]"IServerList и IEnumServer в одном idl описаны?"
Сергей, IServerList и IEnumServer описаны в одном idl. Реализует эти объекты один сервер в экзешнике.
"Судя по тексту ошибки, наиболее вероятно, что проблемы с маршалингом IEnumServer по причине отсутствия Proxy/Stub для него. Посмотри в HCR\Interface, есть ли там этот интерфейс и кто там числится маршалером для него."
Конечно смотрел... Через oleview...
Там прописаны proxy/stub, которые я компилирую из стандартных файлов, генерируемых MIDL. И для IServerList и для IEnumServer в реестре прописана одна и та же библиотека proxy/stub dbsvrps.dll.
"Это стандартное поведение, не обращай внимания, в данном случае значения не имеет."
А вот это для меня новость, честно говоря. Я грешил, что с маршаллером проблемы, поэтому идет запрос этих интерфейсов. Я заблуждаюсь?
Так где копать причину неудачи? Может дать дополнительную информацию?
← →
Владислав © (2005-05-06 17:30) [3]Спасибо!
Вопрос решился.
Ответ по ссылке в первом посте.
← →
Набережных С. © (2005-05-06 18:33) [4]
> Владислав © (06.05.05 17:05) [2]
> Я грешил, что с маршаллером проблемы, поэтому идет запрос
> этих интерфейсов.
Нет, не поэтому. Объект может реализовать эти интерфейсы, а может, как обычно и бывает, не реализовывать. СОМ их запрашивает сразу после создания объекта перед созданием стандартного стаба для первого запрошенного интерфейса, на случай, если объект сам намерен заняться маршалингом и создавать стаб не нужно(IMarshal), либо нужно создать "прокладку" между прокси и объектом(IStdMarshalInfo). Если оба ответа отрицательны, то дальше все идет обычным образом.
> Владислав © (06.05.05 17:30) [3]
М-да..:)))
← →
Владислав © (2005-05-06 19:17) [5]> Набережных С. © (06.05.05 18:33) [4]
Спасибо!
Дело ясное, что дело темное... На лицо явные пробелы в знаниях... Буду устранять...
"СОМ их запрашивает сразу после создания объекта перед созданием стандартного стаба для первого запрошенного интерфейса
..."
Как показывает практика, не только для первого...
Больше всего мне Ваше "М-да..:)))" понравилось ;)
← →
Набережных С. © (2005-05-06 21:01) [6]
> Как показывает практика, не только для первого...
Какая-то неправильная практика:) Оба для каждого объекта вызываются только один раз, сразу после создания объекта, вкупе с некоторыми другими специальными. Если ответил отказом, то второго шанса не будет:)
← →
Набережных С. © (2005-05-06 21:22) [7]В [6] "вызываются" - читать "запрашиваются", в смысле вызывается QueryInterface с ихними IID. Все, спать пора:)
Страницы: 1 вся ветка
Форум: "Corba";
Текущий архив: 2006.03.26;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.042 c