将结构转换为intptr

时间:2014-01-10 22:19:17

标签: 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;

我使用byte []而不是IntPtr类型作为成员p,因为它被用于c#project。

我已经定义了一个对象obj,其中len = 10,p = new byte [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个字节。

有更好的方法吗?

1 个答案:

答案 0 :(得分:3)

返回值正确,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