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

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

本文介绍了PInvoke结构具有未指定长度的数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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#结构定义中为byte[] buf上的MarshalAs属性指定的内容时遇到了麻烦.缓冲区是在.NET端分配的,其长度在调用时是已知的.

I'm having trouble figuring out what to specify for the MarshalAs attribute on byte[] buf in the C# struct definition. The buffer is allocated on the .NET side, and its length is known at call time.

在一个简单的小测试中:

In a simple little test:

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

Foo(ref info);

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

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.

我尝试过:

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

没有任何作用.

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

In general, I really don't know the best way to debug these kinds of problems either.

推荐答案

根据汉斯·帕桑特(Hans Passant)的建议,我实现了以下内容:

Per Hans Passant's suggestion, I implemented the following:

[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;
        }
    }
}

这篇关于PInvoke结构具有未指定长度的数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 21:42