Передать строку через COM интерфейс

 
0
 
C++
ava
Hypertonyc | 04.10.2013, 14:03
День добрый!

Есть приложение(Сервер) на C++ в котором описаны классы


class INamer : public IUnknown
{
public:
   STDMETHOD( GetSharedMemoryName( BSTR )) PURE;   
};

class Namer : public INamer
{
protected:
   // Reference count
   long      m_lRef;
   BSTR     wsSharedMemoryName;

public:
   Namer();
   ~Namer();

public:
   // IUnknown
   STDMETHOD(QueryInterface( REFIID, void** ));
   STDMETHOD_(ULONG, AddRef());
   STDMETHOD_(ULONG, Release());

   // INamer
   STDMETHOD( GetSharedMemoryName( BSTR ));
};

class NamerClassFactory : public IClassFactory
{
protected:
   long       m_lRef;

public:
   NamerClassFactory();
   ~NamerClassFactory();

   // IUnknown
   STDMETHOD( QueryInterface(REFIID, void** ));
   STDMETHOD_(ULONG, AddRef());
   STDMETHOD_(ULONG, Release());

   // IClassFactory
   STDMETHOD( CreateInstance(LPUNKNOWN, REFIID, void**));
   STDMETHOD( LockServer(BOOL));
};


Метод GetSharedMemoryName принимает BSTR (wchar_t*), куда потом копирует wsSharedMemoryName:


Namer::Namer()
{
    m_lRef = 0;

    // Increment the global object count
    InterlockedIncrement( &g_lObjs );

    wsSharedMemoryName = (BSTR)CoTaskMemAlloc(sizeof(OLECHAR)*128);
    memset(wsSharedMemoryName, 0, sizeof(OLECHAR)*128);
    for(int i = 0; i < 127; ++i)
    {
        wsSharedMemoryName[i] = (OLECHAR) ((rand() % 26) + 65);        
    }
}

STDMETHODIMP Namer::GetSharedMemoryName( BSTR chResult )
{
    memcpy(chResult,wsSharedMemoryName,sizeof(OLECHAR)*128);    //здесь брейкпоинт
    return S_OK;
}


Запускаю приложение(клиент)


int main( int argc, char *argv[] )
{
    CoInitialize( NULL );
    IClassFactory *pCF;    
    BSTR str = (BSTR)CoTaskMemAlloc(128*sizeof(OLECHAR));
    IUnknown* pUnknown;
    INamer* pNamer;

    HRESULT hr = CoGetClassObject( CLSID_Namer, CLSCTX_LOCAL_SERVER, NULL, IID_IClassFactory, (void**) &pCF);
    hr = pCF->CreateInstance(NULL,IID_IUnknown, (void**)&pUnknown);    
    pCF->Release();
    hr = pUnknown->QueryInterface(IID_INamer, (void**)&pNamer);
    pUnknown->Release();
    
    hr = pNamer->GetSharedMemoryName(str); // E_OUTOFMEMORY
    pNamer->Release ();

    CoUninitialize();
    return 0;
}


И вызов pNamer->GetSharedMemoryName(str) возвращает ошибку  E_OUTOFMEMORY и str никак не меняется( естественно ). Хотя если поставить брейкпоинт в сервере на memcpy, то видно, что том всё выполняется и копируется наура! Уверен, что есть какая-то мелочь, но какая  smile 
Comments (1)
ava
xvr | 04.10.2013, 15:40 #
Цитата (Hypertonyc @  4.10.2013,  13:03 findReferencedText)
 Уверен, что есть какая-то мелочь, но какая

Есть мелочь, и еще какая! Нельзя в поданную BSTR ничего копировать  smile3 COM подсистема вполне может вклинится (и вклинивается) между вашим сервером и клиентом, а она не в курсе такого 'необычного' способа использования BSTR. Передавайте указатель на BSTR как [out] параметр

PS. BSTR это не просто wchar_t*, у нее перед собственно телом лежит размер, в виде unsigned short
Please register or login to write.
Firm of day
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Contributors
  xvr   Hypertonyc
advanced
Submit