Opc Интерфейс Ienumopcitemattributes

  • Автор темы POlegin
  • Дата начала
P

POlegin

Гость
#1
Всем привет!!! Есть такая проблема. Я пишу свой OPC сервер, и мне нужно реализовать интерфейс IEnumOPCItemAttributes, т.е. это обычный перечеслитель вроде IEnumXXX. Так вот, вся проблема в вызове из клиента метода Next этого интерфейса! Если сервер не запущен, то тогда всё проходит нормально, клиент подключается к серверу, запускается приложение-сервер и т.д. Но если сервер уже запущен клиент подключается к нему, но метод Next возвращает ошибку "Номер находится за пределами допустимого диапазона"!!! В чём дело я не пойму.

Вот код метода Next на сервере:
C++:
HRESULT __stdcall TEnumOPCItemAttributes::Next(
ULONG celt,
OPCITEMATTRIBUTES **ppItemArray,
ULONG *pceltFetched)
{
if( celt == 0 )
{
return E_INVALIDARG;
}

ULONG new_celt = celt;

//m_pItems - это просто указатель на std::vector
if( m_cIndex >= (*m_pItems).size() )
{
*pceltFetched = 0;
return S_FALSE;
}

if( new_celt + m_cIndex > (*m_pItems).size() )
{
new_celt = (*m_pItems).size() - m_cIndex;
}

(*ppItemArray) = (OPCITEMATTRIBUTES*)CoTaskMemAlloc(sizeof(OPCITEMATTRIBUTES)*new_celt);
if( (*ppItemArray) == NULL )
{
return E_OUTOFMEMORY;
}

(*pceltFetched) = new_celt;

ULONG i;
int j;

for( i = m_cIndex, j = 0; i < new_celt + m_cIndex; i++, j++ )
{
(*ppItemArray)[j].szAccessPath = NULL;
(*ppItemArray)[j].szItemID = AllocString((*m_pItems)[i]->Name.c_str());

if( (*ppItemArray)[j].szItemID == NULL )
{
return E_OUTOFMEMORY;
}

(*ppItemArray)[j].bActive = (*m_pItems)[i]->Active;
(*ppItemArray)[j].hClient = (*m_pItems)[i]->ClientHandle;
(*ppItemArray)[j].hServer = (*m_pItems)[i]->ServerHandle;
(*ppItemArray)[j].dwAccessRights = (*m_pItems)[i]->AccessRights;
(*ppItemArray)[j].dwBlobSize = 0;
(*ppItemArray)[j].pBlob = NULL;
(*ppItemArray)[j].vtRequestedDataType = (*m_pItems)[i]->VarType;
(*ppItemArray)[j].vtCanonicalDataType = (*m_pItems)[i]->VarType;
(*ppItemArray)[j].dwEUType = OPC_NOENUM;
VariantInit(&((*ppItemArray)[j].vEUInfo));
(*ppItemArray)[j].vEUInfo.vt = VT_EMPTY;
}

m_cIndex += new_celt;

return S_OK;
}

А вот вызывающий код со стороны клиента:
C++:
ULONG* pFetch = (ULONG*)CoTaskMemAlloc(sizeof(ULONG));
//ULONG pFetch;
OPCITEMATTRIBUTES* Attr = NULL;

hr = pOPCAttr->Next(1,&Attr,pFetch);
if( FAILED(hr) )
{
//Ошибка : "Номер находится за пределами допустимого диапазона"
}