[Mono-dev] Communicating native C structs with managed code
Ivo Smits
Ivo at UFO-Net.nl
Sat Jan 6 20:15:53 UTC 2018
Hi Ramin,
You can pass native pointers between C and C# using the IntPtr, void* or
S1* (where S1 is the struct defined below) in P/Invoke calls. You can
pass a struct to a P/Invoke using the ref modifier, which will, whenever
possible, also pass a pointer to the struct. You can pass a native
pointer from C to a ref parameter in a C# function. To use native
pointers, you have to mark the affected code block as unsafe. For example:
[StructLayout(LayoutKind.Sequential)]
unsafe struct S1 {
public double x;
public double y;
public Int64 z;
public fixed int arr[256];
};
The unsafe keyword marks the structure as unsafe - it can only contain
types which do not need marshalling. StructLayout can be used to specify
the alignment options, usually the default works. StructLayout.Explicit
and the FieldOffset attribute can be used to place fields at arbitrary
offsets, for example to create "unions".
The fixed (int) defines an inline array which behaves like a pointer
(like it would in C). This array can not be used as a regular array, but
its members can be accessed using an index. There's no bounds checking.
You can then pass the struct to an external C function using one of the
following options:
class Test {
[DllImport("native.so")]
public static extern void nativemethod1(ref S1 arg);
[DllImport("native.so")]
public static extern void nativemethod2(S1* arg);
[DllImport("native.so")]
public static extern void nativemethod3(void* arg);
[DllImport("native.so")]
public static extern void nativemethod4(IntPtr arg);
unsafe void Test() {
S1 s = new S1();
nativemethod1(ref s);
nativemethod2(&s); //only works because we're in an unsafe block
and the struct is marked unsafe
nativemethod3(&s);
nativemethod4((IntPtr)(&s));
}
}
The other way around works as well, for example:
class Test {
[DllImport("native.so")]
public static extern S1* nativemethod1();
[DllImport("native.so")]
public static extern IntPtr nativemethod3();
unsafe void Test() {
S1* s = nativemethod1();
s = (S1*)nativemethod3(); //cast if you used an IntPtr
s->x = 6; //the structure can now be modified directly. Make sure
it's not released in the native code...
}
}
--
Ivo
Op 5-1-2018 om 10:59 schreef R Zaghi:
> Hi
>
> What would be the most performance efficient method to pass a native C
> struct of primitive data types (memory aligned or compact) to the
> managed code in Mono/C# and allow modification of its member variables
> in the managed code?
>
> Do we have anything specific in Mono that helps eliminate manual
> marshalling on every call? or could we? :)
>
> Say, in the following scenarios:
>
> struct S1 {
> double x,
> double y,
> double z
> };
>
> Or
>
> struct S2 {
> int arr[256]
> };
>
> Or
>
> struct S3 {
> double x,
> int arr[256]
> };
>
>
>
> Ramin
>
>
>
> --
>
>
>
> Ramin Zaghi
>
> *Mosaic3DX™ | User Interface Technology*
> St John's Innovation Centre,
> Cowley Road,
> Cambridge,
> CB4 0WS, UK*
> *
> *E*:**rzaghi at mosaic3dx.com <mailto:rzaghi at mosaic3dx.com>
> *T*: +44 1223 421 311
> http://linkedin.com/in/raminzaghi
>
>
>
> _______________________________________________
> Mono-devel-list mailing list
> Mono-devel-list at lists.dot.net
> http://lists.dot.net/mailman/listinfo/mono-devel-list
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.dot.net/pipermail/mono-devel-list/attachments/20180106/6ecc65a3/attachment.html>
More information about the Mono-devel-list
mailing list