0

i am trying to pass an array of struct exported from a c# library to c++ code. the objective is to pass SAFEARRAY of struct from c++ to c#.

I have followed instructions from

http://limbioliong.wordpress.com/2011/07/16/marshaling-a-safearray-of-managed-structures-by-com-interop-part-2/

but getting this error with the call GetRecordInfoFromTypeInfo

0x80028019 Old format or invalid type library.

TrustyCoder
  • 4,749
  • 10
  • 66
  • 119
  • Is there a reason why this didn't help (http://stackoverflow.com/questions/12503041/passing-an-array-of-structs-from-c-sharp-to-c-using-com-callable-wrapper/12508525#12508525)? Do you really need to have a SAFEARRAY? Does it have to be a struct? Do you need to implement a dispatch interface? – Zdeslav Vojkovic Sep 21 '12 at 19:31
  • The earlier attempt was to pass structures from C# to c++ and now I am doing the reverse. The problem with LPArray marshalling is that it marshalled only one element in the array and to variable length arrays were not bound to the array defined in the C# signature. So I had to change the marshall it to Safearray instead. Please let me know if the previous method works without any change. – TrustyCoder Sep 21 '12 at 19:38
  • Then this part is a bit confusing: "i am trying to pass an array of struct exported from a c# library to c++ code". I am surprised that LPArray marshals only one element (from unmanaged to managed) – Zdeslav Vojkovic Sep 21 '12 at 19:44
  • I have defined all the structures using c# code for convenience. I am using those structures from c++. in the first case i was getting back structures from C++ and now i am pushing the structures into c#. when i am doing this i was marshalling it as LPArrary and declaring as MyStruct[] mystruct in the C# signature but only one element was being passed. I could send multiple elements by setting the sizeconst property but it would be hard coded. any way to pass structures populated from c++ to c#. – TrustyCoder Sep 21 '12 at 19:51
  • I have added an answer, but unfortunately I don't have any Windows machine until monday, so I can't try it. If you don't get it solved by then, I will take a look on Monday – Zdeslav Vojkovic Sep 21 '12 at 20:04

2 Answers2

1

If you don't need to have a dispinterface, following should work:

void MyMethod([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] MyStruct[] data, long size);

If you need to use SAFEARRAY, I would expect following to work (but I am not 100% sure, as I don't have Windows machine available at the moment):

void MyMethod([MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VarEnum.VT_USERDEFINED)] MyStruct[] data);

If you can afford to change your struct to class then this will also work, and save you from UDT hassle:

void MyMethod([MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VarEnum.VT_UNKNOWN)] MyStruct[] data);
Zdeslav Vojkovic
  • 14,391
  • 32
  • 45
1

Does the struct contains strings? If so, make sure to tag them [MarshalAs(UnmanagedType.BStr)]. There is a limitation in COM: strings in arrays of structs must be BSTRs. TLBExp defaults to LPWSTR and then the call dies. See here: http://msdn.microsoft.com/en-us/library/z6cfh6e6(v=vs.100).aspx

JurekM
  • 76
  • 4