Communicating native C structs with managed code

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Communicating native C structs with managed code

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
T: +44 1223 421 311


_______________________________________________
Mono-devel-list mailing list
[hidden email]
http://lists.dot.net/mailman/listinfo/mono-devel-list
Reply | Threaded
Open this post in threaded view
|

Re: Communicating native C structs with managed code

Ivo Smits

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
T: +44 1223 421 311



_______________________________________________
Mono-devel-list mailing list
[hidden email]
http://lists.dot.net/mailman/listinfo/mono-devel-list


_______________________________________________
Mono-devel-list mailing list
[hidden email]
http://lists.dot.net/mailman/listinfo/mono-devel-list