I need to return an array of structure (classes) from a C# library to an unmanaged C++ client. This is the function in the C# library:
[ComVisible(true)]
[Serializable]
public sealed class RetrieverProxy : IRetrieverProxy
{
public IMyRecord[] RetrieveMyRecords(long[] ids)
{
IList<IMyRecord> result = new List<IMyRecord>();
for (int i = 0; i < ids.Count(); i++)
{
result.Add(new MyRecord()
{
// some test data
});
}
return result.ToArray();
}
}
MyRecord
itself contains an array of structures, which are also COM visible and contain a double and a DateTime field.
I get the follow wrapper from regasm:
inline SAFEARRAY * IRetrieverProxy::RetrieveMyRecords (SAFEARRAY * ids) {
SAFEARRAY * _result = 0;
HRESULT _hr = raw_RetrieveMyRecords(ids, &开发者_如何学运维_result);
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return _result;
}
From the client code, I invoke the library like the following:
SAFEARRAY *pMyRecordsSA;
SAFEARRAY *pIds;
// omitting pIds initialization, because from the library I can see
// that they are ok
pMyRecordsSA = pIRetrieverProxy->RetrieveMyRecords(pIds);
The problem I have is how to retrieve the results which are now stored in pMyRecordsSA
. I have tried the following but I it's not working:
IMyRecordPtr pIMyRecords(__uuidof(MyRecord));
HRESULT hr = SafeArrayAccessData(pMyRecordsSA, (void**)&pIMyRecords);
but then trying to use the pIMyRecords
pointer gives an access violation (hr
is 0K).
Any ideas? I am really stuck on this.
It turned out that I just needed "another level of indirection". That is, a pointer to pointer vs a simple pointer.
IMyRecords** pIMyRecords;
HRESULT hr = SafeArrayAccessData(pMyRecordsSA, (void**)&pIMyRecords);
This did the trick.
Take a look at CComSafeArray it might save you some time.
精彩评论