M
Michael
Hi all,
I've written a COM-Dll (with ATL) that holds a database of marathon
runners. I wrote a function that returns the needed information of all
runners and it works fine in VB but not in VB.NET. I'm using an array
of structs as a return value. Here's the code of the function:
*************************************************
const IID ResultUDT_IID = {... };
STDMETHODIMP CDatabase::ResultAll(SAFEARRAY **pResult)
{
t_Result *Results = NULL;
ResultUDT *pData = NULL;
if (!m_bResult)
{
HRESULT hr = Error( _T("No result available!") );
return hr;
}
IRecordInfo *pUdtRecordInfo = NULL;
HRESULT hr = ::GetRecordInfoFromGuids(LIBID_SOFTLib, 1, 0, 0,
ResultUDT_IID, &pUdtRecordInfo );
if (FAILED(hr))
{
HRESULT hr2 = Error( _T("Can not create RecordInfo interface
for ResultUDT") );
return hr;
}
int RecordsCnt = MyDB->Cnt();
Results = My->Result;
SAFEARRAYBOUND rgsabound[1];
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = RecordsCnt ;
*pResult = ::SafeArrayCreateEx( VT_RECORD, 1, rgsabound,
pUdtRecordInfo );
pUdtRecordInfo->Release();
if (*pResult == NULL)
{
HRESULT hr2 = Error( _T("Can not create array of ResultUDT
structures") );
return hr2;
}
hr = ::SafeArrayAccessData(*pResult, (void**)&pData);
if (FAILED(hr))
return( hr );
for (int i=0; i<RecordsCnt; i++, pData++)
{
pData->Pnr = Results.pnr;
pData->Score = Results.Score;
CComBSTR bstrID = MyDB->PersonInfo[Results.tnr].ID;
bstrID.CopyTo(&pData->ID);
CComBSTR bstrFilepath = Results.Filepath;
bstrFilepath.CopyTo(&pData->Filepath);
}
hr = ::SafeArrayUnaccessData(*pResult);
return hr;
}
*************************************************
In the idl.-File I defined my struct as:
*************************************************
typedef
[uuid(...),
helpstring("Result Structure")]
struct ResultUDT
{
int Pnr;
int Score;
BSTR ID;
BSTR Filepath;
} ResultUDT;
*************************************************
and my interface looks like that:
*************************************************
interface INet : IDispatch
{
[id(1), helpstring("Result")]
HRESULT Result([out, retval] SAFEARRAY(struct ResultUDT)
*pResult);
}
*************************************************
In VB I can use that function and it works fine:
*************************************************
Dim res() as ResultUDT
....
res = DB.Result(5)
txtName.text = res(0).ID
*************************************************
In VB.NET I have written the following code (which somehow needs the
lib-name SOFTLib in front of the struct):
*************************************************
Dim res() as SOFTLib.ResultUDT
....
res = DB.Result(5)
txtName.text = res(0).ID
*************************************************
and that always brings up "System.IndexOutOfRangeException" because my
array "res" has the length 0.
Any ideas to this problem?
Thanks
Michael
I've written a COM-Dll (with ATL) that holds a database of marathon
runners. I wrote a function that returns the needed information of all
runners and it works fine in VB but not in VB.NET. I'm using an array
of structs as a return value. Here's the code of the function:
*************************************************
const IID ResultUDT_IID = {... };
STDMETHODIMP CDatabase::ResultAll(SAFEARRAY **pResult)
{
t_Result *Results = NULL;
ResultUDT *pData = NULL;
if (!m_bResult)
{
HRESULT hr = Error( _T("No result available!") );
return hr;
}
IRecordInfo *pUdtRecordInfo = NULL;
HRESULT hr = ::GetRecordInfoFromGuids(LIBID_SOFTLib, 1, 0, 0,
ResultUDT_IID, &pUdtRecordInfo );
if (FAILED(hr))
{
HRESULT hr2 = Error( _T("Can not create RecordInfo interface
for ResultUDT") );
return hr;
}
int RecordsCnt = MyDB->Cnt();
Results = My->Result;
SAFEARRAYBOUND rgsabound[1];
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = RecordsCnt ;
*pResult = ::SafeArrayCreateEx( VT_RECORD, 1, rgsabound,
pUdtRecordInfo );
pUdtRecordInfo->Release();
if (*pResult == NULL)
{
HRESULT hr2 = Error( _T("Can not create array of ResultUDT
structures") );
return hr2;
}
hr = ::SafeArrayAccessData(*pResult, (void**)&pData);
if (FAILED(hr))
return( hr );
for (int i=0; i<RecordsCnt; i++, pData++)
{
pData->Pnr = Results.pnr;
pData->Score = Results.Score;
CComBSTR bstrID = MyDB->PersonInfo[Results.tnr].ID;
bstrID.CopyTo(&pData->ID);
CComBSTR bstrFilepath = Results.Filepath;
bstrFilepath.CopyTo(&pData->Filepath);
}
hr = ::SafeArrayUnaccessData(*pResult);
return hr;
}
*************************************************
In the idl.-File I defined my struct as:
*************************************************
typedef
[uuid(...),
helpstring("Result Structure")]
struct ResultUDT
{
int Pnr;
int Score;
BSTR ID;
BSTR Filepath;
} ResultUDT;
*************************************************
and my interface looks like that:
*************************************************
interface INet : IDispatch
{
[id(1), helpstring("Result")]
HRESULT Result([out, retval] SAFEARRAY(struct ResultUDT)
*pResult);
}
*************************************************
In VB I can use that function and it works fine:
*************************************************
Dim res() as ResultUDT
....
res = DB.Result(5)
txtName.text = res(0).ID
*************************************************
In VB.NET I have written the following code (which somehow needs the
lib-name SOFTLib in front of the struct):
*************************************************
Dim res() as SOFTLib.ResultUDT
....
res = DB.Result(5)
txtName.text = res(0).ID
*************************************************
and that always brings up "System.IndexOutOfRangeException" because my
array "res" has the length 0.
Any ideas to this problem?
Thanks
Michael