Marshaling structure members

S

Sin

Hello everybody,

I'm currently trying to understand how marshaling can use used for accessing
Win32 API functions as well as custom C/C++ code we design which exposes
functions the same way as the Win32 API.

I figured how to use strings... No problem there, there was a couple undred
examples on the net. I have yet to find how to do the same with an array of
integers for example... Here's my test code :

C strucure I'm trying to match :

typedef struct {
char name[200];
long id;
double a;
bool b;
char c;
short d[100];
} struct1;


Here's the VB structure in it's current (non working) state :

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi, Pack:=4)> _
Private Structure struct1

<VBFixedString(200), MarshalAs(UnmanagedType.ByValTStr, SizeConst:=200)>
_
Public name As String

Public id As Int32
Public a As Double
Public b As Boolean
Public c As Char

<VBFixedArray(100), MarshalAs(UnmanagedType.I2, SizeConst:=100)> _
Public d() As Int16

End Structure


Two different problems occur using this definition. First, the
Marshall.SizeOf() call on an instance of the structure gives me this msg:

An unhandled exception of type 'System.ArgumentException' occurred in
WindowsApplication2.exe

Additional information: Le type struct1 ne peut pas être marshalé comme une
structure non managée ; il n'est pas possible de calculer une taille ou un
offset.

Rough traduction from french :

The struct1 type cannot be marshalled as an unmanaged type ; it is
impossible to calculate a size or an offet.

I don't quite understand why I get this message, or what it means for that
matter.


The second problem is that if I modify the member "d" from my C DLL, I get
the following error :

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

Additional information: Impossible de marshaler le champ d du type struct1 :
ce type ne peut pas être marshalé comme un champ structuré.

Rough traduction from french :

Unable to marshall the d "field" of struct1 : this type cannot be marshaled
as a structured "field".

I've been looking over MSDN and the internet all morning and I still can't
figure how to make this work...

Any help would be appreciated!

Alex.
 
A

Armin Zingler

Sin said:
<VBFixedArray(100), MarshalAs(UnmanagedType.I2, SizeConst:=100)>
_ Public d() As Int16

Does

<VBFixedArray(100), MarshalAs(UnmanagedType.BYVALARRAY, SizeConst:=100)> _
Public d() As Int16


work?

Marshal.sizeof(gettype(struct1)) returns 420 then. Seems to be correct.


I don't know, but isn't the C type "long" (field 'id') also "long" in
VB.NET?
 
S

Sin

Does
<VBFixedArray(100), MarshalAs(UnmanagedType.BYVALARRAY, SizeConst:=100)> _
Public d() As Int16

work?

Marshal.sizeof(gettype(struct1)) returns 420 then. Seems to be correct.

Yes!

I did have to change my boolean declaration, either of these work :

C++ bool (C++ base type) = <MarshalAs(UnmanagedType.U1)> Public b As Boolean
C++ BOOL (ie : macro for int) = Public b As Boolean

I don't know, but isn't the C type "long" (field 'id') also "long" in
VB.NET?

Not sure where I picked that from but I'm fairly sure VB.NET's Long (as
opposed to any other language I know of) is 64 bits, rather than the 32 bits
an experienced programmer has come to expect. I guess they're laying the
grounds for the 64 bit version of Windows... It's odd nonetheless..

In other words, an unmanaged C/C++ long (a standard one that is) is either
an integer or an Int32 (which I find clearer). You never know when they're
going to change Integer to a 64 bit either, so better be safe than sorry!

Thanks alot for clearing it up!

Alex.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top