В
общем
, не догоняю чего
-то
, решил сперва не передавать объект,
попытаться просто вызывать то
т же метод(methodKot) интерфейса(InterfaceKot)
, что
при стандартном маршалинге , но перевести его на ручной маршалинг
--------------------------------------------------------------------------------------
SERVER.exe
Сервер самый обычный так сказать классический SERVER.EXE
CLSID_ObjectKot - компонент ObjectKot (и его же надо передать - абсолютная задача)
IID_InterfaceKot - есть у Кота один интерфейс - InterfaceKot
Клиент делает простой вызов
//------------------------------------------------------------------------------
// CLIENT.exe - клиент
CoInitialize(0);
CoGetClassObject( CLSID_ObjectKot , CLSCTX_LOCAL_SERVER, NULL,
IID_IClassFactory, (void **) &pClassFactory);
InterfaceKot * i_kot=NULL;
hr=pClassFactory->CreateInstance(
NULL ,
IID_InterfaceKot,
(void**)&i_kot );
на сервере один компонет и один интерфейс
-----------------------------------------------------------------------------
SERVER.exe
//========IUnknown_kot тот же IUnknown , что бы не было накладок ,
//========а то IMarshal тоже использует IUnknown
class IUnknown_kot
{
public:
virtual STDMETHODIMP QueryInterface(REFIID riid, void ** ppAny)=0;
virtual STDMETHODIMP_(ULONG) AddRef()=0;
virtual STDMETHODIMP_(ULONG) Release()=0;
};
//=====интерфейс
interface InterfaceKot :public IUnknown_kot
{
virtual HRESULT __stdcall methodKot ()=0;
};
//=====компонент
class ObjectKot : public IMarshal , public InterfaceKot
{
public:
ObjectKot();
~ObjectKot();
// IUnknown
................QueryInterface , addRef , Release тут
// IMarshal
.......................GetUnmarshalClass
.......................GetMarshalSizeMax
.......................MarshalInterface
.......................UnmarshalInterface
.......................ReleaseMarshalData
.......................DisconnectObject
// InterfaceKot
virtual HRESULT __stdcall methodKot (){ cout<<"Hello Kot"<<endl;}
//variables
static long active_component; //глобальный счетчик всех компонентов
ULONG m_refCount; //приватный счетчик одного компонента
};
---------------------------------------------------------------------
Один момент, надо учесть в QueryInformation riid == IID_IMarshal
STDMETHODIMP ObjectKot::QueryInterface(REFIID riid, void ** ppAny)
{
//---------------------------------------------
if(riid == IID_IUnknown) { *ppAny = this; }
else if(riid == IID_InterfaceKot) { *ppAny =(InterfaceKot*) this; }
else if(riid == IID_IMarshal) { *ppAny = (IMarshal*) this; }
else{ *ppAny = NULL;
return E_NOINTERFACE;
}
//---------------------------------------------
((IUnknown *)(*ppAny))->AddRef();
return S_OK;
}
Теперь надо пройтись по методам IMarshal в ObjectKot
и первый метод который получит вызов
при ручном маршалинге GetUnmarshalClass
тут нужно передать CLSID объекта который вроде бы как должен будет
появиться у клиента и создать и передать указатель на интерфейс , или объект или данные какие)
Тут так запутано что нигде толком я не нашел объяснения что это за CLSID
STDMETHOD(GetUnmarshalClass)
(REFIID riid, void * pv, DWORD dwDestContext, void * pvDestContext, DWORD mshlFlags, CLSID* pCid )
{
//===ВАРИАНТЫ ТАКИЕ:
*pCid = CLSID_ObjectKot; // по идее это должен быть ObjectKot
// *pCid =IID_InterfaceKot; // а могет быть и это
//*pCid = CLSID_какого_еще_Proxy????; // какой то неизвестный мне вариант??????
return S_OK;
}
Следующий вызовется метод GetMarshalSizeMax
STDMETHOD(GetMarshalSizeMax)
(REFIID riid, void * pv, DWORD dwDestContext, void * pvDestContext, DWORD mshlFlags, ULONG* pSize )
{
// передаем размер желаемого буфера
// sizeof(ЗАГОЛОВОК) + sizeof(active_component) + sizeof(m_refCount) ;
*pSize = 3 * sizeof (DWORD);
return S_OK;
}
и теперь очередь дойдет до MarshalInterface
Система выделила уже буфер-Stream
, и мы положим туда значения переменных ObjectKot и заголовок
Упрощенно это выглядит так
STDMETHOD(MarshalInterface)
(IStream* pStm, REFIID riid, void *pv, DWORD dwDestContext, void * pvDestContext, DWORD mshlFlags)
{
AddRef();
DWORD dw = 0xFF669900; //ЗАГОЛОВОК
pStm->Write(&dw, sizeof(DWORD), 0);
dw = this->m_refCount;
hr = pStm->Write(&dw, sizeof(DWORD), 0);
dw = this->active_component;
return pStm->Write(&dw, sizeof (DWORD), 0);
}
Обратная распаковка данных из Stream , на стороне клиента(с проверкой Endian)
Но почему[color=red][b]-т[/b][/color]о она уже не срабатывает ???????????????
STDMETHOD(UnmarshalInterface)(IStream* pStm, REFIID riid, void ** ppv )
{
*ppv = 0;
DWORD dw; ULONG cbRead;
// read endian header
// читаем заключительный заголовок
DWORD dw;
ULONG cbRead;
HRESULT hr = pStm->Read(&dw, sizeof (DWORD), &cbRead);
if (FAILED(hr) || cbRead != sizeof(DWORD)) return RPC_E_INVALID_DATA;
//============
bool bSwapEndian = dw == 0x009966FF;
hr = pStm->Read(&dw, sizeof(DWORD), &cbRead);
this->m_refCount = dw;
if (FAILED(hr) || cbRead != sizeof(DWORD)) return RPC_E_INVALID_DATA;
// ============
hr = pStm->Read(&dw, sizeof(DWORD), &cbRead);
this->active_component = dw;
if (FAILED(hr) || cbRead != sizeof(DWORD)) return RPC_E_INVALID_DATA;
// ============
// byte swap members if necessary
// байт переставляет свои биты, если необходимо
if (bSwapEndian) MessageBox(0 , "UnMarshalInterface","1-2",0);//byteswapdata(&m_x, &m_y);
// return pointer to this object
}
Два последних метода
, соответственно
, тоже не вызываются?
??
STDMETHOD (ReleaseMarshalData)(IStream *pStm)
{
return S_OK;
}
STDMETHOD (DisconnectObject)(DWORD dwReserved)
{
return S_OK;
}
Короче не работало и не работает