Маршаллинг интерфейса.
От: -comm- http://forum.sukhoi.ru/forumdisplay.php?f=120
Дата: 06.05.05 06:59
Оценка:
Здравствуйте.

Проблема в следующем.

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

Подскажите пожалуйста, в каком направлении искать ошибку? Что я не так сделал?
Re: Маршаллинг интерфейса.
От: Vi2 Удмуртия http://www.adem.ru
Дата: 06.05.05 11:29
Оценка:
Здравствуйте, -comm-, Вы писали:

C>Класс для интерфейса IEnumServer реализован с помощью шаблонов вот так:

C>// Declaration of the CEnumServer
C>typedef _CopyInterface<IServer> CServerCopy;
C>typedef CComEnum<IEnumServer, &CLSID_EnumServer, IServer *, CServerCopy> CEnumServer;//Class;

А для чего CLSID_EnumServer? Нужен именно GUID интерфейса, а не кокласса.
typedef CComEnum<IEnumServer, &IID_EnumServer, IServer *, CServerCopy> CEnumServer;
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[2]: Маршаллинг интерфейса.
От: Аноним  
Дата: 06.05.05 13:29
Оценка:
Здравствуйте, Vi2, Вы писали:

Vi2>Здравствуйте, -comm-, Вы писали:


C>>Класс для интерфейса IEnumServer реализован с помощью шаблонов вот так:

Vi2>
C>>// Declaration of the CEnumServer
C>>typedef _CopyInterface<IServer> CServerCopy;
C>>typedef CComEnum<IEnumServer, &CLSID_EnumServer, IServer *, CServerCopy> CEnumServer;//Class;
Vi2>

Vi2>А для чего CLSID_EnumServer? Нужен именно GUID интерфейса, а не кокласса.
Vi2>
Vi2>typedef CComEnum<IEnumServer, &IID_EnumServer, IServer *, CServerCopy> CEnumServer;
Vi2>



Елки палки! Спасибо огромное! Действительно, проблема в этом!
Спасибо!
Re[2]: Маршаллинг интерфейса.
От: Владислав Сомов http://forum.sukhoi.ru/forumdisplay.php?f=120
Дата: 06.05.05 15:25
Оценка:
Здравствуйте, Vi2, Вы писали:

Vi2>Здравствуйте, -comm-, Вы писали:


C>>Класс для интерфейса IEnumServer реализован с помощью шаблонов вот так:

Vi2>
C>>// Declaration of the CEnumServer
C>>typedef _CopyInterface<IServer> CServerCopy;
C>>typedef CComEnum<IEnumServer, &CLSID_EnumServer, IServer *, CServerCopy> CEnumServer;//Class;
Vi2>

Vi2>А для чего CLSID_EnumServer? Нужен именно GUID интерфейса, а не кокласса.
Vi2>
Vi2>typedef CComEnum<IEnumServer, &IID_EnumServer, IServer *, CServerCopy> CEnumServer;
Vi2>


Вот я так и не въехал в разницу... Можете популярно объяснить, если, конечно, время позволяет?
Re[3]: Маршаллинг интерфейса.
От: Vi2 Удмуртия http://www.adem.ru
Дата: 12.05.05 04:42
Оценка:
Здравствуйте, Владислав Сомов, Вы писали:

C>>>typedef CComEnum<IEnumServer, &CLSID_EnumServer, IServer *, CServerCopy> CEnumServer;//Class;
Vi2>>typedef CComEnum<IEnumServer, &IID_EnumServer, IServer *, CServerCopy> CEnumServer;

ВС>Вот я так и не въехал в разницу... Можете популярно объяснить, если, конечно, время позволяет?

GUID или UUID — глобальный (или универсальный) идентификационный номер.
CLSID_EnumServer — GUID кокласса — уникально идентифицирует класс компонента, чтобы его можно было создать через CoCreateInstance и пр.
IID_EnumServer — GUID интерфейса — уникально идентифицирует интерфейс, чтобы его можно было запрашивать у объекта через QueryInterface и пр.

Как правило, GUIDы идентифицируют отдельные сущности и не пересекаются, хотя есть и исключения, которые проистекают из автоматизации. Например, кокласс прокси автоматически имеют CLSID, равный IID первого интерфейса из набора интерфейсов, поддерживаемых этой прокси. И т.д.

Поэтому для шаблона CComEnum<IEnumServer, &CLSID_EnumServer,...>:
— запрашивать интерфейс с IID_EnumServer бесполезно, потому что он откликнется только на "интерфейс", имеющий GUID, равный CLSID_EnumServer,
— а запрашивать интерфейс с CLSID_EnumServer ни у кого и мысли не возникнет, потому что его не существует в природе.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.