Groups | Blog | Home
all groups > dotnet interop > july 2003 >

dotnet interop : Marshalling for two dimensional arrays


michael_lappin2003 NO[at]SPAM yahoo.co.uk
7/11/2003 7:54:59 AM
I am trying to pass a VB.Net structure to a C unmanaged DLL.

The C structure has the following format

typedef struct MessageStruct
{
char Messages[100][400];
byte NumberOfMessages;
} MessageStruct

In VB.Net I am trying to redeclare a corresponding structure as
follows

Public Struct MessageStruct
Messages()() As Char
NumberOfMessages As Byte
End Struct

Have also used DLL import to alias the C function within VB.Net. In C
the parameter list looks like this

MessageStruct& Msg

In the aliased VB.Net sub routine the parameter list I have defined is
as follows

ByRef Msg As MessageStruct

When this function is called within VB.Net I get the following error
message

An unhandled exception of type 'System.TypeLoadException' occurred
in
vbTestApp.exe

Additional information: Can not marshal field Msg of type
Messages:
This type can not be marshaled as a structure field.

Does anyone have any idea what type of Attributes I have to use to
make this possible, at the moment I am using

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
Public Structure MessageStruct
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=100)> _
Public Messages As String()
Public NumberOfMessages As Int32
End Structure

or

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
Public Structure MessageStruct
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=100)> _
Public Messages()() As char
Public NumberOfMessages As Int32
End Structure

Neither work, so any suggestions would be greatly appreciate as I am a
Mattias Sjögren
7/11/2003 6:15:11 PM
Michael,

Try it like this

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> _
Public Structure MessageStruct
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=400*100)> _
Public Messages() As char
Public NumberOfMessages As Byte
End Structure



Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/
Michael Lappin
7/14/2003 3:19:44 AM

Thanks for that, seems to work fine, wouldn't have worked that out. But
follows the way arrays are constructed in C.

Nice one.


*** Sent via Developersdex http://www.developersdex.com ***
Michael Lappin
7/14/2003 6:20:45 AM
Hello Mattias,

have encountered another problem hoping you may be able to help me with
it,

have increased the character array in C to have dimensions [20][4096]

have set SizeConst:=4096*20

when I marshal that and send it to the function get the following
exception

structure to complex or to large, seems towork at with dimensions

1650*20

any idea what the problem may be.

Bye



*** Sent via Developersdex http://www.developersdex.com ***
Mattias Sjögren
7/16/2003 12:34:54 AM
Michael,

[quoted text, click to view]

Interesting, I guess the interop marshaler has some size limit then.

What you could try as a workaround is allocate some memory from the
unmanaged heap with one of the Marshal.Alloc methods, and then copy
the data there (you might have copy it in smaller chunks), and then
finally pass the IntPtr pointer to that memory location to the
imported function instead.



Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/
AddThis Social Bookmark Button