[Mono-list] CustomMarshaler for structure element using P/Invoke
Jonathan Pryor
jonpryor at vt.edu
Tue Nov 15 06:52:32 EST 2005
On Mon, 2005-11-14 at 19:54 -0800, Bill Medland wrote:
> Can any expert on P/Invoke tell me if what I want to do is
> impossible; it's looking that way to me.
It's possible, it just depends on how much manual work you want to do.
> I want to make P/Invoke calls with structures containing strings,
> but unfortunately they aren't quite strings in the usual sense.
> I can almost get there by using ByValTStr on the strings but
> unfortunately I don't want them null-terminated; I want fixed
> well-known lengths (specified by the SizeConst parameter of the
> attribute).
Then ByValTStr isn't for you, as it should always null-terminate the
strings (for sanity/safety reasons).
Instead of ByValTStr, you can use ByValArray for a byte[] array...
> For example in C I have
>
> typedef struct {
> unsigned short length;
> char mystring1 [8];\
> signed int myint;
> char mystring2 [12];
> } mystruct;
>
> void myfunc (const mystruct *input);
Becomes the following C# code:
struct mystruct {
public ushort length;
[MarshalAs (UnmanagedType.ByValArray, SizeConst=8)]
public byte[] mystring1;
public int myint;
[MarshalAs (UnmanagedType.ByValArray, SizeConst=12)]
public byte[] mystring2;
}
class Imports {
[DllImport ("...")]
private static extern void myfunc (ref mystruct input);
}
> I just about see how I could do this if I marshal the whole
> structure myself but I actually want to let the default
> marshaling handle the hard work and just let me marshal the char
> arrays (since actually there are several structures)
The char arrays are now byte arrays, so you can either fill the byte
arrays directly, or you can use Encoding.GetBytes() to get a byte array
from a string:
mystruct input = new mystruct ();
input.length = 16;
input.mystring1 = Encoding.UTF8.GetBytes ("12345678");
input.myint = 32;
input.mystring2 = Encoding.UTF8.GetBytes ("123456789ABC");
myfunc (ref input);
> I don't see any documentation anywhere that explains in enough
> detail how the custom marshaling occurs to let me do this. Does
> anyone know?
http://www.mono-project.com/dllimport
Attached is a working example program. Compile & run as:
gcc -g -shared -o libmedland.so medland.c
mcs medland.cs
mono medland.exe
- Jon
-------------- next part --------------
A non-text attachment was scrubbed...
Name: medland.c
Type: text/x-csrc
Size: 547 bytes
Desc: not available
Url : http://lists.ximian.com/pipermail/mono-list/attachments/20051115/7ce2f5a6/medland.bin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: medland.cs
Type: text/x-csharp
Size: 645 bytes
Desc: not available
Url : http://lists.ximian.com/pipermail/mono-list/attachments/20051115/7ce2f5a6/medland-0001.bin
More information about the Mono-list
mailing list