Russian Qt Forum

Программирование => С/C++ => Тема начата: Nalsur1982 от Мая 11, 2010, 12:29



Название: Обнуление указателя
Отправлено: Nalsur1982 от Мая 11, 2010, 12:29
Привет! Может кто поможет найти ошибку? у меня при возвращении из функции enumCLSID обнуляется указатель. pEnumGUID.
Код:
#include <stdio.h>
#include <windows.h>
#include "opccomn.h"  
#include "opcda.h"
#include "OLECTL.h"  
#include "COMCAT.h"
#include "opccomn_i.c"
#include "opcda_i.c"
#include "OpcEnum_h.h"
#include "OpcEnum_i.c"

HRESULT enumCLSID(LPTSTR szHostName, CATID catid, DWORD dwClsCtx, IEnumGUID* pEnumGUID);
HRESULT enumPROGID(LPTSTR szHostName, CATID catid, DWORD dwClsCtx);

EXTERN_C const CATID CATID_OPCDAServer10;  
EXTERN_C const CATID CATID_OPCDAServer20;

int main(int argc, char** argv)
{
// USES_CONVERSION;
HRESULT hr;

printf("Start programm.\r\n");
if (FAILED(CoInitializeEx(NULL, COINIT_MULTITHREADED)))
{
printf("CoInitializeEx failed.\r\n");
return -1;
};

// CATID catid[] = {CATID_OPCDAServer10,CATID_OPCDAServer20,CATID_OPCDAServer30,CATID_XMLDAServer10};
hr = enumPROGID(NULL, CATID_OPCDAServer20, CLSCTX_LOCAL_SERVER);
if(FAILED(hr))
{
printf("enumPROGID failed.\n");
}

CoUninitialize();
return 0;

}
HRESULT enumCLSID(LPTSTR szHostName, CATID catid, DWORD dwClsCtx, IEnumGUID* pEnumGUID)
{  
HRESULT hr;
COSERVERINFO cInfo;
memset(&cInfo, 0, sizeof(cInfo));
cInfo.pwszName = szHostName; //T2OLE()
cInfo.pAuthInfo = NULL;
cInfo.dwReserved1 = NULL;
cInfo.dwReserved2 = NULL;

MULTI_QI cResults;
memset(&cResults, 0, sizeof(cResults));
cResults.pIID = &IID_IOPCServerList;
cResults.pItf = NULL;
cResults.hr = S_OK;

hr = CoCreateInstanceEx(CLSID_OpcServerList, NULL, dwClsCtx, &cInfo,1,&cResults);
if (FAILED(hr))  
{  
        printf("CoCreateInstanceEx failed.\n");
        return hr;  
    }

if (FAILED(cResults.hr))  
{  
        printf("QueryInterface IID_IOPCServerList failed.\n");
        return cResults.hr;  
    }

IOPCServerList* pOPCServerList = (IOPCServerList*)cResults.pItf;

// pEnumGUID = NULL;
IEnumGUID* p_enumGUID = NULL;
hr = pOPCServerList->EnumClassesOfCategories(1, &catid, 1, &catid, &pEnumGUID);
if (FAILED(hr))  
    {  
        printf("EnumClassesOfCategories failed.\n");
if(pOPCServerList)pOPCServerList->Release();
pOPCServerList = NULL;
pEnumGUID = NULL;
        return hr;  
    }  

if(pOPCServerList)pOPCServerList->Release();

return S_OK;
}

HRESULT enumPROGID(LPTSTR szHostName, CATID catid, DWORD dwClsCtx)
{
HRESULT hr;
IEnumGUID* pEnumGUID = NULL;
hr = enumCLSID(szHostName, catid, dwClsCtx, pEnumGUID);
if(FAILED(hr))
{
printf("Function enumCLSID failed.\n");
return hr;
}

hr = pEnumGUID->Reset();

GUID guid;    
ULONG fetched = 0;

hr = pEnumGUID->Reset();
if(FAILED(hr))
{
printf("pEnumGUID->Reset() failed.\n");
return hr;
}

hr = pEnumGUID->Next(1,&guid,&fetched);
if(FAILED(hr))
{
printf("pEnumGUID->Next() failed.\n");
return hr;
}

while (hr == S_OK && fetched > 0)
{
LPOLESTR progID;
::ProgIDFromCLSID(guid,&progID);

char name[512];
::WideCharToMultiByte(CP_ACP,0,progID,-1,name,512,0,NULL);

printf("Name = %s\n", name);
hr = pEnumGUID->Next(1,&guid,&fetched);
}
return S_OK;
}


Название: Re: Обнуление указателя
Отправлено: registrationfedser87 от Мая 11, 2010, 12:36
У тебя строка неверна
Код:
if(pEnumGUID=NULL)
Ты не сравниваешь-ты присваиваешь (ты знак = пропустил)


Название: Re: Обнуление указателя
Отправлено: Nalsur1982 от Мая 11, 2010, 12:40
Не, эту проверку (присвоение) забыл убрать просто, сорри, она вообще не нужна. Указатель обнуляется (смотрел отладчиком) при возврате из функции (return).


Название: Re: Обнуление указателя
Отправлено: registrationfedser87 от Мая 11, 2010, 13:01
Ну единственное место в ф-ии, где по идее может быть обнуление-это или в ф-ии EnumClassesOfCategories, или когда срабатывает условие:
Код
C++ (Qt)
hr = pOPCServerList->EnumClassesOfCategories(1, &catid, 1, &catid, &pEnumGUID);
if (FAILED(hr))


Название: Re: Обнуление указателя
Отправлено: Nalsur1982 от Мая 11, 2010, 13:09
Наверное не то. Если вызывать enumCLSID из main то все нормально. И в отладчике до конца процедуры указатель ссылается на участок памяти и только после выхода из функции (уже за фигурной закрывающей скобкой) указатель сбрасывается в NULL. Мне так думается проблема в передаче параметра pEnumCLSID в функциях. Только вот где, понять не могу. Если что то сам объект создается в EnumClassesOfCategories.


Название: Re: Обнуление указателя
Отправлено: registrationfedser87 от Мая 11, 2010, 13:19
а зачем ты применяешь операцию & к указателю строке
Код:
pOPCServerList->EnumClassesOfCategories(1, &catid, 1, &catid, &pEnumGUID)
Передавай просто указатель pEnumGUID без &.


Название: Re: Обнуление указателя
Отправлено: Nalsur1982 от Мая 11, 2010, 13:23
Так требуется для этой функции, вот ее объявление (эта функция не моя, из стандарта OPC Foundation, и я к ней доступа не имею):
virtual HRESULT STDMETHODCALLTYPE EnumClassesOfCategories(
            /* [in] */ ULONG cImplemented,
            /* [size_is][in] */ CATID rgcatidImpl[  ],
            /* [in] */ ULONG cRequired,
            /* [size_is][in] */ CATID rgcatidReq[  ],
            /* [out] */ IEnumGUID **ppenumClsid) = 0;


Название: Re: Обнуление указателя
Отправлено: ритт от Мая 11, 2010, 14:38
а покажи объявление IEnumGUID ?

/* какое отношение это имеет к кутэ? спрашивайте подобное на мелкософтовских форумах */


Название: Re: Обнуление указателя
Отправлено: Nalsur1982 от Мая 11, 2010, 14:53
к Qt не имеет отношение. Просто в основном здесь смотрю информацию. Решил путем замены на IEnumGUID**:
HRESULT enumCLSID(LPTSTR szHostName, CATID catid, DWORD dwClsCtx, IEnumGUID** pEnumGUID);