I'm currently running into an issue of needing to pass a SAFEARRAY(GUID) as a return value from C++ to C#.
Currently the C# side is using an Interop dll generated from Tlbimp.exe (Type Library Importer).
The IDL is:
HRESULT GetGuids(
[out]SAFEARRAY(GUID)* guids);
I've also tried [out, retval]
The function signature is:
HRESULT
WINAPI
MyClass::GetGuids(SAFEARRAY** guids)
If I use SafeArrayCreate()
or SafeArrayCreateVector()
:
SAFEARRAY* psa
psa = SafeArrayCreate(VT_CLSID, 1, rgsabound);
I get a NULL SAFEARRAY
pointer, which is supposed to indicate E_OUTOFMEMORY
which is incorrect.
What I did find was that VT_CLSID
is only for Ole property sets and not SAFEARRAY's:
http://poi.apache.org/apidocs/org/apache/poi/hpsf/Variant.html Its indicated that CLSID is
I've also tried the alternate means of constructing the safe array with:
SafeArrayAllocDescriptor()
and SafeArrayAllocData()
.
hResult = SafeArrayAllocDescriptor(1, guids)
hResult = SafeArrayAllocData(*guids);
This lets me create the array, but when populating it with SafeArrayPutElement()
I get an HRESULT of 0x80070057 (The parameter is incorrect). This is probably due to the fact it takes the VT_CLSID
parameter as well
I can populate it manually with SafeArrayAccessData()
GUID* pData = NULL;
hResult = SafeArrayAccessData(*guids, (void**)&pData);
but I get an error from the C# side: "The value does not fall within the expected Range"
I'm not sure how to accomplish the desired functionality of returning a SAFEARRAY(GUID) to C# either by a retval or out parameter.
It seems it should be simple - there are many areas in the IDL where I'm already passing GUID's without any UDT's or marshalling. Everything works fine until I need to pass them in a SAFEARRAY.
Any help is appreciated, Thanks in advance