3

私はネイティブ関数を使用していますが、C# での構造体のマーシャリングに小さな問題があります。別の構造体に構造体へのポインターがあります-たとえば、C#宣言:

    [StructLayout(LayoutKind.Sequential, Pack=1, CharSet = CharSet.Auto)]
    public struct PARENT
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public string Name;
        [MarshalAs(UnmanagedType.Struct, SizeConst=8)]
        public CHILD pChild;
    }

    [StructLayout(LayoutKind.Sequential, Pack=1, CharSet = CharSet.Auto)]
    public struct CHILD
    {
        public UInt32 val1;
        public UInt32 val2;
    }

PARENT 構造体には、CHILD 構造体へのポインターが必要です。API 関数の引数として (PARENT 構造体の) 「参照へのポインター」を渡す必要があります。

単一の参照 (インポートされた dll 関数の引数として「ref PARENT」) には問題はありませんが、「ref ref」を渡す方法は? アンセーフ コード (C ポインターを使用) を使用せずに可能ですか?

挨拶アーサー

4

2 に答える 2

1

安全でないコードを使用したくない場合は、Child を IntPtr として定義し、Child IntPtr の値にアクセスするプロパティを追加する必要があります。

    [StructLayout(LayoutKind.Sequential, Pack=1, CharSet = CharSet.Auto)]
public struct PARENT
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
    public string Name;
    public IntPtr pChild;
    public CHILD Child{
      get {
       return (CHILD)Marshal.PtrToStructure(pChild, typeof(CHILD));
      }
    }
}

[StructLayout(LayoutKind.Sequential, Pack=1, CharSet = CharSet.Auto)]
public struct CHILD
{
    public UInt32 val1;
    public UInt32 val2;
}

安全でないコード/ポインターを使用すると、より簡単でクリーンになると思います。

于 2012-06-28T08:52:08.560 に答える
0

ここでは妥当だと思うので、これは安全と危険の組み合わせです。

fixed (void* pt = new byte[Marshal.SizeOf(myStructInstance)])
{
    var intPtr = new IntPtr(pt);
    Marshal.StructureToPtr(myStructInstance, intPtr, true);

    // now "pt" is a pointer to your struct instance
    // and "intPtr" is the same, but wrapped with managed code
}
于 2012-06-28T08:53:08.793 に答える