I have a C++ COM local server and C# client. The server code:
// MyStruct as define in the _i.h file
typedef /* [uuid] */ DECLSPEC_UUID("...") struct MyStruct
{
SAFEARRAY * FormatData;
LONG aLong;
BOOL aBool;
} MyStruct;
// Server method being invoked
STDMETHODIMP CMyClass::Foo(MyStruct* StreamInfo, int* result)
{
long Length;
BYTE* Data;
GetData(Length, Data);
PackBytes(Length, Data, &(StreamInfo->FormatData));
}
PackBytes
converts the BYTE
array to SAFEARRAY
. It is taken from this stackoverflow question. It sets the boundary & dimension of the SAFEARRAY
.
The client code:
MyStruct myStruct;
int rc = obj.Foo(out myStruct);
Where MyStruct
is imported from the COM assembly. it appears as
public struct MyStruct
{
public Array FormatData;
int aLong;
int aBool;
}
After running Foo
appears the error "SafeArray cannot be marshaled to this array type because it has either nonzero lower bounds or more than one dimension" with additional remark "Make sure your array has the required number of dimensions".
When debugging the server code it seems Data
is properly populated in FormatData
: as can be seen in screen-shot below. cElements
equals Length
and the 18 data pieces are equal to the ones in Data
.
Hard-coding Length = 1
did not help. Removing the PackByets
call made the error disappear (other fields were passed ok). How can this be fixed?
The PackBytes
method that you have referenced constructs a SAFEARRAY
with lower bound of 1. Constructing it with a lower bound of zero may fix the problem:
SAFEARRAYBOUND bound{ count, 0 };