Robert Jordan said:
It definitely works. It's an usual interop trick: marshal the
string as byte[], convert the byte[] to string, split on '\0'.
I can understand how this would work for a known-length byte[], but the
length in this case is variant (0..n strings of 0..m length) and I'm not
allocating it, in the struct it's simply byte[]. If the strings were fixed
length (as they are on the call-side that results in this data) then there's
some solutions, as would be the case if it were an array of
pointers-to-strings.
FYI I tried a number of solutions to "directly cast" the data into the
string array before using the byte[] trick, but it seems that the runtime
doesn't allow the obvious ones. For instance, the nicest solution would be to
do it this way...
[MarshalAs(UnmanagedType.ByValArray, ArraySubType=UnmanagedType.LPStr,
SizeConst=numFlds)]
string[] data
but that's apparently illegal and returns the "you can't marshal this
struct" error. I guess that makes sense, it needs to know the size of the
overall struct when doing the mapping back into the managed side. Various
attempts at char[] failed for the same reason.
I was able to debug it a little by saying it was an IntPtr (as a
placeholder) and then using PtrToString on that address. Then I could just
loop on PtrToString by making a new IntPtr + strLen. This almost works, I can
get the first 32 bits (4 chars) back OK but from that point on the data is
mushed and says that the string is always 11 chars long (which it isn't). If
I can figure that out I think I'll go this route, and get rid of the byte[].