How to use pinvoke for C structure pointer for C #

I am trying to use pinvoke to sort an array of structures inside another structure from C to C #. AFAIK, no. So instead, in the C structure, I declare ptr for my array and malloc. Problems: 1) How to declare an equivalent on the C # side? 2) How to distribute and use the equivalent on the C # side?

//The C code typedef struct { int a; int b; } A; typedef struct { int c; // A myStruct[100]; // can't do this, so: A *myStruct; } B; //The c# code: [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public class A{ int a; int b; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public class B{ int c; // can't declare array of [100] A structures... ? } 

[EDIT]: Somehow I misinterpreted what I read elsewhere on a fixed array of objects from C #. And I can fix the size of the array in C So, ok compiled, but then I get a "link to an object not installed on an object instance" when using:

data.B[3].a = 4567; So, after reading elsewhere what this error is, I added this method:

 public void initA() { for (int i = 0; i < 100; i++) { B[i] = new A(); } } 

OK compiled again, but with the same msg error.

+4
source share
1 answer

To create "complex" structures like the one between C and C #, you have several options.

In this case, I highly recommend that you embed a fixed array in the C-side structure, as this will simplify the C # side. You can use the MarshalAs attribute to tell C # how much space it needs to allocate in the array at runtime:

 // In C: typedef struct { int a; int b; } A; typedef struct { int c; A data[100]; } B; // In C#: [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct A { int a; int b; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct B { int c; [MarshalAs(UnmanagedType.LPArray, SizeConst=100)] A[] data = new data[100]; } 

If you don’t know or cannot specify a fixed size for your array, then you will need to do what you did and declare it as a pointer to C. In this case, you cannot tell C # how much memory the array will use at runtime so you are pretty much stuck in doing it all manually. This question has a good summary of how this works, but the basic idea is:

  • You should add a field to your structure, which includes the number of elements in the array (this will greatly simplify your life).
  • Declare a field in C # as: IntPtr data; without attributes.
  • Use Marshal.SizeOf(typeof(A)) to get the size of the structure in unmanaged memory.
  • Use Marshal.PtrToStructure to convert a single unmanaged structure in C #
  • Use IntPtr.Add(ptr, sizeofA) to go to the next array structure
  • Loop until you finish.
+5
source

All Articles