Pae*_*ula 4 c c# arrays pinvoke struct
我试图使用pinvoke来编组从C到C#的另一个结构内的结构数组.AFAIK,没有办法.
所以相反,在C结构中,我向我的数组和malloc声明了一个ptr.问题:1)如何在C#端声明等效?2)如何在C#端分配和使用等效的?
//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...
?
}
Run Code Online (Sandbox Code Playgroud)
[编辑]:不知何故,我误解了我在别处读到的关于c#侧固定数组对象的内容.我可以在C中修复数组大小所以编译好了,但是在使用时我得到"对象引用未设置为对象的实例":
data.B[3].a = 4567; 所以,在其他地方读到这个错误可能是什么,我添加了这个方法:
public void initA()
{
for (int i = 0; i < 100; i++) { B[i] = new A(); }
}
Run Code Online (Sandbox Code Playgroud)
再次,编译好,但相同的错误消息.
要在C和C#之间编组这样的"复杂"结构,你有几个选择.
在这种情况下,我强烈建议您尝试将固定数组嵌入到C端结构中,因为它会大大简化C#端.您可以使用该MarshalAs属性告诉C#在运行时需要在阵列中分配多少空间:
// 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];
}
Run Code Online (Sandbox Code Playgroud)
如果您不知道或无法指定数组的固定大小,那么您将需要执行您所做的操作并将其声明为C中的指针.在这种情况下,您无法告诉C#多少内存该数组将在运行时使用,所以你几乎完全坚持用手工编组.这个问题很好地说明了它是如何工作的,但基本的想法是:
IntPtr data;没有属性.Marshal.SizeOf(typeof(A))在非托管内存中获取结构的大小.Marshal.PtrToStructure一个单一的非托管结构转换为C#IntPtr.Add(ptr, sizeofA)移动到下一个结构数组中