Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: COM/DCOM/ActiveX/ATL/CORBA > COM-компонент возвращает клиенту нулевые указатели


Автор: yaprogrammer 7.10.2009, 13:00
При первом запуске клиента все проходит нормально. При Debugе клиента все проходит нормально. При втором и последующих запусках возращает нулевой указатель.  Сервер всегда пишет в лог правильные данные.
Код клиента 
Код

DWORD dwCount = 5;
DWORD* pphServer;
HRESULT* ppErrors;

HRESULT hr = pServer->GetItems(dwCount, &pphServer, &ppErrors);
if(SUCCEEDED(hr))
{
       for(DWORD ii = 0; ii < dwCount; ii++)
      {
           cout << ii << ") " << pphServer[ii] << "\n";            
      }
}
CoTaskMemFree(ppErrors);
CoTaskMemFree(pphServer);


Код компонента
Код

HRESULT CServer::GetItems(
    DWORD        dwCount,    
    DWORD** pphServer,
    HRESULT**   ppErrors
)
{       
    if (dwCount == 0 || ppErrors == NULL)
    {        
        return E_INVALIDARG;
    }
    
    *pphServer = GetServerItems(dwCount); //здесь выделяется память и записываются данные
    
    *ppErrors = (HRESULT*)CoTaskMemAlloc(sizeof(HRESULT) * dwCount);

    bool bError = false;

    for (DWORD ii = 0; ii < dwCount; ii++)
    {
        if ((*pphServer)[ii] == NULL)
        {
            (*ppErrors)[ii] = S_FALSE;
            bError = true;
        }
        else
               {
                        GetLogFile().Print((*pphServer)[ii]); // вывожу в лог
                        (*ppErrors)[ii] = S_OK;
                }
    }
    
    return (bError)?S_FALSE:S_OK;
}





Автор: jonie 7.10.2009, 15:19
yaprogrammer, ну и ? Отладчик запретили что ли? Отлаживайте компонент - кто вам мешает ? Наставьте assert-ов наконец...

Автор: Andrey44 8.10.2009, 07:07
Цитата(yaprogrammer @  7.10.2009,  13:00 Найти цитируемый пост)
При втором и последующих запусках возращает нулевой указатель. 

значит надо смотреть *pphServer = GetServerItems(dwCount); //здесь выделяется память и записываются данные
Почему GetServerItems возвращает пустой указатель.

Автор: yaprogrammer 8.10.2009, 09:44
А подскажите пожалуйста как отлаживать компонент в msvc 6.0?

Автор: jonie 8.10.2009, 11:25
yaprogrammer, абсолютно также как и в VS2010. Стартуете отладчик, только запускаемым exe-шником (студия спросит вас) указываете нечто, что ипользует ваш компонент (да хоть IE например). И всё.

Автор: yaprogrammer 9.10.2009, 10:02
jonie Я так понимаю, что это работает для компонента в dll. А у меня компонент реализован в exe.

Andrey44 Вставил проверку на пустой указатель - память выделяется нормально.

Уже начал грешить на код IDL:
Код

Interface IX
[
    object,
    uuid(32BB8326-B41B-11CF-A6BB-0080C7B2D682),
    helpstring("IX Interface"),
    pointer_default(unique),
    dual,
    oleautomation
]
interface IX : IDispatch
{
    import "oaidl.idl" ;

    HRESULT GetItems(
    [in]                                               DWORD        dwCount,    
    [out, size_is(,dwCount)]                DWORD** pphServer,
    [out, size_is(,dwCount)]                HRESULT**   ppErrors
    );
    
} ;

//
// Component and type library descriptions
//
[
    uuid(9992140f-b6d6-4584-b765-ef2aa1aca2ab),
    version(1.0),
    helpstring("My Type Library")
]
library ServerLib
{
    importlib("stdole32.tlb") ;

    // Component
    [
        uuid(298fe0b3-6242-46cc-8a39-372bcdc7f68f),
        helpstring("Component Class")
    ]
    coclass Component
    {
        [default] interface IX ;        
    } ;
} ;





И является ли правильным выделение памяти с помощью CoTaskMemAlloc когда компонент и клиент в разных процессах?

Автор: Andrey44 9.10.2009, 10:42
Цитата(yaprogrammer @  7.10.2009,  13:00 Найти цитируемый пост)
При втором и последующих запусках возращает нулевой указатель.
Нулевой указатель чего?

Цитата(yaprogrammer @  9.10.2009,  10:02 Найти цитируемый пост)
И является ли правильным выделение памяти с помощью CoTaskMemAlloc когда компонент и клиент в разных процессах
Да, правильно

Автор: yaprogrammer 9.10.2009, 10:46
Нулевой указатель pphServer и ppErrors.

Автор: Andrey44 9.10.2009, 10:52
Цитата(yaprogrammer @  9.10.2009,  10:02 Найти цитируемый пост)
Вставил проверку на пустой указатель - память выделяется нормально.

Что-то я вас не пойму.
Покажите как проверяете

Автор: yaprogrammer 9.10.2009, 10:58
После выделения памяти на сервере проверяю так
Код

if(*pphServer == NULL || *ppErrors == NULL)
{
      return E_OUTOFMEMORY;
}

Автор: Andrey44 9.10.2009, 11:49
Так где-же возвращается нулевой указатель?
Сделайте так
Код

if(*pphServer == NULL)
{
      return E_OUTOFMEMORY;
}

 || *ppErrors == NULL я думаю проверять не надо, так как обычно ppErrors == NULL при успешном выполнении функции.
По этому вы постоянно и возвращаете из функции E_OUTOFMEMORY

Автор: xvr 9.10.2009, 12:02
Судя по IDL у вас интерфейс IX dispinterface и dual, но типы параметров pphServer и ppErrors несовместимы с dispinterface  smile 
Какой код возврата (hr в клиенте в строке 6)?

Автор: yaprogrammer 9.10.2009, 13:20
Cоздал новый компонент, указал другие uuid, сделал проверку на пустой указатель как говорил Andrey44. Теперь возвращает не пустые указатели. но значения не те, точнее только первое значение массива то:
На сервере записываю следующие значения: 10, 11, 12, 13, 14

А на клиенте считываю: 10, 0, 1296387404, 8, 1244932

При этом код возврата функции hr = 0.

Цитата

типы параметров pphServer и ppErrors несовместимы с dispinterface  

xvr, а какими они должны быть?


Автор: xvr 9.10.2009, 13:58
Цитата(yaprogrammer @ 9.10.2009,  13:20)
Cоздал новый компонент, указал другие uuid, сделал проверку на пустой указатель как говорил Andrey44. Теперь возвращает не пустые указатели. но значения не те, точнее только первое значение массива то:
На сервере записываю следующие значения: 10, 11, 12, 13, 14

А на клиенте считываю: 10, 0, 1296387404, 8, 1244932

При этом код возврата функции hr = 0.

Похоже size_is считается в байтах, а не в элементах (что логично). Попробуйте так
Код

    HRESULT GetItems(
    [in]                                               DWORD        dwCount,    
    [out, size_is(,dwCount*4)]                DWORD** pphServer,
    [out, size_is(,dwCount*4)]                HRESULT**   ppErrors
    );


Цитата

Цитата

типы параметров pphServer и ppErrors несовместимы с dispinterface  

xvr, а какими они должны быть?
SAFEARRAY
А вам точно нужен dispinterface? Может и обычного IUnknown хватит?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)