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 に答える