5

C 定义

typedef struct {
    const uint8_t* buf;
    int bufLen;
} Info;


int Foo(Info* info);

C# 定义

[StructLayout(LayoutKind.Sequential)]
public struct Info
{
     // [MarshalAs( ??? )]
     public byte[] buf;
     int bufLen
}    

[DllImport(...)]
public static extern int Foo(ref Info info);

我无法弄清楚在 C# 结构定义中为MarshalAs属性指定什么。byte[] buf缓冲区是在 .NET 端分配的,它的长度在调用时是已知的。

在一个简单的小测试中:

var info = new Info {
    buf = new byte[] {0x40, 0x50, 0x60, 0x70},
    bufLen = 4,
};

Foo(ref info);

一切似乎都正常工作,但实际上我缓冲区中的数据不正确。从我看到的 DLL 中打印出来01 00 80 00- 不确定那是什么。

我试过了:

  • MarshalAs
  • [MarshalAs(UnmanagedType.SafeArray)]

没有任何效果。

一般来说,我也真的不知道调试这类问题的最佳方法。

4

2 回答 2

4

根据 Hans Passant 的建议,我实施了以下操作:

[StructLayout(LayoutKind.Sequential)]
public struct Info : IDisposable
{
    private IntPtr buf;
    private int bufLen;

    public Info(byte[] buf) : this() {
        this.buf = Marshal.AllocHGlobal(buf.Length);
        Marshal.Copy(buf, 0, this.buf, buf.Length);
        this.bufLen = buf.Length;
    }

    public void Dispose() {
        if (buf != IntPtr.Zero) {
            Marshal.FreeHGlobal(buf);
            buf= IntPtr.Zero;
        }
    }
}
于 2013-03-25T00:52:24.320 回答
0

我知道为时已晚.. 但以防万一有人来这里寻求答案。

我终于想出了类似练习的下一个解决方案。

[StructLayout(LayoutKind.Sequential)]
public struct Info
{
     [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
     public byte[] buf;
     int bufLen
}

来自 MSDN

数组可以作为 UnmanagedType.ByValArray 封送,这需要您设置 MarshalAsAttribute.SizeConst 字段。大小只能设置为常数。

在我的情况下,缓冲区大小为 8 个字节。

于 2015-05-14T13:51:11.697 回答