From: Werner Lemberg on
[I managed to send this twice to microsoft.public.vb.general.discussion
instead of sending it to this newsgroup... Sorry if you probably read it a
third time here.]


Folks,


consider these cascading C structures:

typedef struct AA_
{
int aa1;

} AA;

typedef struct BB_
{
int numAA;
AA *AAs;

} BB;

typedef struct CC_
{
int numBB;
BB *BBs;

} CC;

which have been allocated dynamically. How can I marshal this in VB.net
2008?

I tried this:

<StructLayout(LayoutKind.Sequential)> _
Public Structure AA
Public aa1 As Integer
End Structure

<StructLayout(LayoutKind.Sequential)> _
Public Structure BB
Public numAA As Integer
<MarshalAs(UnmanagedType.LPArray, SizeParamIndex := 0)> _
Public AAs() As Point
End Structure

<StructLayout(LayoutKind.Sequential)> _
Public Structure CC
Public numBB As Integer
<MarshalAs(UnmanagedType.LPArray, SizeParamIndex := 0)> _
Public BBs() As Point
End Structure

using `IntPtr' instead of the `CC' structure everywhere if I don't have to
access the contents of the cascading arrays. However, at one place I
actually have to access it, and converting `IntPtr' to `CC' with

Marshal.PtrToStructure(foo, GetType(CC)), CC)

fails with a TypeLoadException.

After hours of reading web resources I've finally come to this article

http://www.itags.org/dotnet/1288074/

which mentions that using Marshal.Copy might work. However, I consider this
quite inelegant. Since I have control over the C code (using the C compiler
which comes with MS Visual Studio 9.0) I wonder whether I can `help' the
marshalling process on the C side to avoid this additional copying in case
there is no other possibility. The SAFEARRAY macro comes to my mind,
however, I haven't yet found the right document which covers such cascading
structures and gives a decent introduction.

Note that I'm not a Windows user, and I use the Visual Studio compilers on
the command line only, so please be patient with me :-)


Werner