How to invoke native MyFunction(MyStruct* myStructs, unsigned int nMyStructs) from C#?
-
These are some C# class members:
[StructLayout(LayoutKind.Sequential)]
unsafe struct MyStruct
{
public int size;
public byte* data;
}//...
[DllImport("MyStruct.dll", CharSet = CharSet.Unicode)]
static extern unsafe void MyFunction(MyStruct* myStructs, unsigned int nMyStructs);How to create such array of MyStruct in C# as in C to pass it to MyFunction from C#?
//C version
unsigned int N = 10;
MyStruct* pMyStructs = (MyStruct*)malloc(N * sizeof(MyStruct));
//for i=1:N allocate pMyStruct[i].data with malloc, put some byte data where
MyFunction(pMyStructs, N);//C# version?
//How to allocate and fill those entries from managed byte[] arrays?Чесноков
-
These are some C# class members:
[StructLayout(LayoutKind.Sequential)]
unsafe struct MyStruct
{
public int size;
public byte* data;
}//...
[DllImport("MyStruct.dll", CharSet = CharSet.Unicode)]
static extern unsafe void MyFunction(MyStruct* myStructs, unsigned int nMyStructs);How to create such array of MyStruct in C# as in C to pass it to MyFunction from C#?
//C version
unsigned int N = 10;
MyStruct* pMyStructs = (MyStruct*)malloc(N * sizeof(MyStruct));
//for i=1:N allocate pMyStruct[i].data with malloc, put some byte data where
MyFunction(pMyStructs, N);//C# version?
//How to allocate and fill those entries from managed byte[] arrays?Чесноков
you need to rewrite the MyStruct in C# using the MarshalAs attribute at the vars declaration. something like above :) its only a example ^^ you need to take a look at the mapping of your C byte* to C#..
[StructLayout(LayoutKind.Sequential)] unsafe struct MyCSharpStruct { public int size; public IntPtr data; [MarshalAs(UnmanagedType.ByValTStr,SizeConst=32)] public string MyString; // C -> unsigned char MyString[32]; } [DllImport("MyStruct.dll")] static extern void MyFunction(ref MyCSharpStruct myStructs, unsigned int nMyStructs);
-
These are some C# class members:
[StructLayout(LayoutKind.Sequential)]
unsafe struct MyStruct
{
public int size;
public byte* data;
}//...
[DllImport("MyStruct.dll", CharSet = CharSet.Unicode)]
static extern unsafe void MyFunction(MyStruct* myStructs, unsigned int nMyStructs);How to create such array of MyStruct in C# as in C to pass it to MyFunction from C#?
//C version
unsigned int N = 10;
MyStruct* pMyStructs = (MyStruct*)malloc(N * sizeof(MyStruct));
//for i=1:N allocate pMyStruct[i].data with malloc, put some byte data where
MyFunction(pMyStructs, N);//C# version?
//How to allocate and fill those entries from managed byte[] arrays?Чесноков
You can allocate the memory whereever you want. A simple solution might be to allocate it in managed memory as .NET array:
MyStruct[] myStructs = new MyStruct[N];
fixed (MyStruct* pMyStructs = myStructs) {
// fixed statement ensures the GC doesn't move the memory block while we access it using an unmanaged pointer
MyFunction(pMyStructs, N);
}In this case, the GC will take care of freeing the memory. You can also allocate on the stack (if N is small, for large N you would risk a stack overflow):
MyStruct* pMyStructs = stackalloc MyStruct[N];
MyFunction(pMyStructs, N);In this case, the memory is freed immediately when leaving the function that allocated it. If you want to allocate in the unmanaged heap, then use one of the allocation functions in the
Marshal
class:IntPtr memory = Marshal.AllocHGlobal(N * sizeof(MyStruct));
try {
MyStruct* pMyStructs = (MyStruct*)memory.ToPointer();
MyFunction(pMyStructs, N);
} finally {
Marshal.FreeHGlobal(memory);
}You could use
Marshal.Copy
to copy data from a managed array to an unmanaged pointer - but if you already have a managed array, you can simply use the first approach (fixed statement) to pass that without having to copy anything.