将结构转换为 intptr

Tyl*_*den 3 c# class marshalling intptr

我有一个类定义如下:

[StructLayout(LayoutKind.Sequential)]
public class OUR_MEM_STR
            {
                public byte[] p;
                public int  len;
            };
Run Code Online (Sandbox Code Playgroud)

这是以下 C 结构的等效定义:

typedef struct
{
    void *p;
    int  len;
} OUR_MEM_STR;
Run Code Online (Sandbox Code Playgroud)

我使用 byte[] 而不是 IntPtr 类型作为成员 p 因为它在整个 c# 项目中的使用方式。

我用 len = 10 和 p = new byte[10] 定义了一个对象 obj

我想让它成为一个intptr。我如何获得对象的大小?

 IntPtr pObj = Marshal.AllocHGlobal(obj.len + sizeof(int));
 Marshal.StructureToPtr(obj, pObj, true);
Run Code Online (Sandbox Code Playgroud)

看看我在那里做了什么。它似乎太硬编码。如果我执行以下代码段;

IntPtr pObj = Marshal.AllocHGlobal(Marshal.SizeOf(obj));
Run Code Online (Sandbox Code Playgroud)

这样做会返回错误的大小,因为 obj.p 返回的大小是 4 而不是 10。因为指向字节数组的指针占用的内存是 4 字节。

有没有更好的办法?

Han*_*ant 5

返回值是正确的,p是一个指针,需要4个字节。

你不能这样,有两个内存分配。编组器为数组分配了内存。它创建了一个 SAFEARRAY,一个 COM 数组类型。您的 C 代码不太可能对此感到满意。改为这样声明:

[StructLayout(LayoutKind.Sequential)]
public class OUR_MEM_STR {
    public IntPtr p;
    public int len;
};
Run Code Online (Sandbox Code Playgroud)

并使用 Marshal.AllocHGlobal(10) 分配p. 不要忘记再次清理。

不要将true传递给 StructureToPtr(),AllocHGlobal() 分配的内存未初始化。这会随机崩溃你的程序。你必须通过false