C# 将结构转换为intptr
我有一个类定义如下:C# 将结构转换为intptr,c#,class,marshalling,intptr,C#,Class,Marshalling,Intptr,我有一个类定义如下: [StructLayout(LayoutKind.Sequential)] public class OUR_MEM_STR { public byte[] p; public int len; }; 这是以下C结构的等效定义: typedef struct { void *p; int len; } OUR_MEM_STR; 我对成员p使
[StructLayout(LayoutKind.Sequential)]
public class OUR_MEM_STR
{
public byte[] p;
public int len;
};
这是以下C结构的等效定义:
typedef struct
{
void *p;
int len;
} OUR_MEM_STR;
我对成员p使用byte[]而不是IntPtr类型,因为它在整个c#project中的使用方式
我定义了一个对象obj,len=10,p=newbyte[10]
我想把它做成一个intptr。我如何获得该对象的大小
IntPtr pObj = Marshal.AllocHGlobal(obj.len + sizeof(int));
Marshal.StructureToPtr(obj, pObj, true);
看看我在那里做了什么。它似乎太难编码了。如果我做下面的片段
IntPtr pObj = Marshal.AllocHGlobal(Marshal.SizeOf(obj));
这样做会返回错误的大小,因为obj.p返回的大小是4而不是10。因为指向字节数组的指针占用的内存是4字节
有更好的方法吗?返回值正确,
p
是指针,需要4个字节
您不能让它这样,有两个内存分配。封送拆收器为数组分配了内存。它创建了一个SAFEARRAY,一种COM数组类型。您的C代码不太可能对此感到满意。改为这样声明:
[StructLayout(LayoutKind.Sequential)]
public class OUR_MEM_STR {
public IntPtr p;
public int len;
};
并使用Marshal.AllocHGlobal(10)分配p
。别忘了再打扫一次
如果不将true传递给StructureToPtr(),则AllocHGlobal()分配的内存未初始化。这会使你的程序随机崩溃。您必须通过false。您能告诉我们您试图复制的结构的C定义吗?@JaredPar,我编辑了这个问题,所以,如果我执行IntPtr pObj=Marshal.AllocHGlobal(Marshal.SizeOf(obj));并且使用假参数,应该可以吗?这太酷了,它做到了。当我将结构写入ptr函数时,intellisense提示告诉我使用true。他们把新的开发人员搞糊涂了谢谢!C#垃圾收集不会自动清理吗?不会,您分配了非托管内存。调用Marshal.FreeHGlobal()两次是一项困难的要求。请注意,这必须在Pinvoke代码停止使用struct.Correct后发生。我正在掌握平沃克。多亏了像SOOnce上的u这样的ppl,就在我离开创建对象的函数之前,还有一次?一次用于数组,另一次用于结构。两人都必须被释放。