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 字节。
有没有更好的办法?
返回值是正确的,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。