简体   繁体   English

具有未指定长度数组的PInvoke结构

[英]PInvoke struct with array of unspecified length

C definitions C定义

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


int Foo(Info* info);

C# definitions C#定义

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

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

I'm having trouble figuring out what to specify for the MarshalAs attribute on byte[] buf in the C# struct definition. 我在查找C#struct定义中byte[] bufMarshalAs属性的内容时遇到了麻烦。 The buffer is allocated on the .NET side, and its length is known at call time. 缓冲区在.NET端分配,其长度在调用时已知。

In a simple little test: 在一个简单的小测试中:

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

Foo(ref info);

Everything seems to be working correctly, but in fact the data in my buffer is incorrect. 一切似乎都正常,但事实上我的缓冲区中的数据是不正确的。 Printing it out from the DLL I see 01 00 80 00 - not sure what that is. 从DLL打印我看到01 00 80 00 - 不知道那是什么。

I've tried: 我试过了:

  • No MarshalAs 没有MarshalAs
  • [MarshalAs(UnmanagedType.SafeArray)]

and nothing works. 没有任何作用。

In general, I really don't know the best way to debug these kinds of problems either. 一般来说,我真的不知道调试这些问题的最佳方法。

Per Hans Passant's suggestion, I implemented the following: 根据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;
        }
    }
}

I know it is too late.. but just in case if some one come here for an answer. 我知道为时已晚......但是如果有人来这里寻求答案的话。

I finally came up with next solution for similar exercise. 我终于想出了类似练习的下一个解决方案。

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

From MSDN 来自MSDN

Arrays can be marshaled as UnmanagedType.ByValArray, which requires you to set the MarshalAsAttribute.SizeConst field. 数组可以编组为UnmanagedType.ByValArray,它要求您设置MarshalAsAttribute.SizeConst字段。 The size can be set only as a constant. 大小只能设置为常量。

In my case the buffer size is 8 bytes. 在我的情况下,缓冲区大小是8个字节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM