Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Передать строку через COM интерфейс 
:(
    Опции темы
Hypertonyc
  Дата 4.10.2013, 13:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 68
Регистрация: 19.10.2008

Репутация: нет
Всего: нет



День добрый!

Есть приложение(Сервер) на 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 
PM MAIL   Вверх
xvr
Дата 4.10.2013, 15:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Цитата(Hypertonyc @  4.10.2013,  13:03 Найти цитируемый пост)
 Уверен, что есть какая-то мелочь, но какая

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

PS. BSTR это не просто wchar_t*, у нее перед собственно телом лежит размер, в виде unsigned short

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: COM/DCOM/ActiveX/ATL/CORBA | Следующая тема »


 




[ Время генерации скрипта: 0.1549 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.