0

私はそのような構造体をCで書きました

struct IMAGE {
    unsigned int    x, y;
    unsigned char   **data;
};

この構造体を C# で使用するためにマーシャリングする方法を教えてください。

私の解決策は機能しません。

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class IMAGE
{
            public UInt32 x;
            public UInt32 y;

            public byte[][] data;
};
4

2 に答える 2

1

マネージ配列はポインターとは異なります。マネージド配列には配列のサイズが必要であり、構造体をマーシャリングしようとしている場合は、直接マーシャリングするための固定サイズが必要です。

属性SizeConstのパラメーターを使用して、データがマーシャリングされるときのデータのサイズを設定できます。MarshalAs

xしかし、とyは画像の寸法であり、 のサイズはdataこれらの変数に依存すると推測しています。ここでの最善の解決策は、 としてマーシャリングし、IntPtr必要なときにデータにアクセスすることです。

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class IMAGE
{
    public UInt32 x;
    public UInt32 y;

    private IntPtr data;

    public byte[][] Data
    {
        get
        {
            byte[][] newData = new byte[y][];

            for(int i = 0; i < y; i++)
            {
                newData[i] = new byte[x];
                Marshal.Copy(new IntPtr(data.ToInt64() + (i * x)), newData[i], 0, x);
            }

            return newData;
        }

        set
        {
            for (int i = 0; i < value.Length; i++)
            {
                Marshal.Copy(value[i], 0, new IntPtr(data.ToInt64() + (i * x)), value[i].Length);
            }
        }
    }
}

アンセーフ コードの使用が許可されている場合は、 を に変更IntPtrbyte**て直接操作できます。

セッターを使用すると、アンマネージ メモリにやみくもに書き込む前に、値の次元を確認したくなるでしょう。

于 2012-06-01T03:53:59.803 に答える
-1

私の推測では、それは次のとおりです。

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class IMAGE
{
            public UInt32 x;
            public UInt32 y;

            public ref IntPtr data;
};

非常に便利なリファレンスは p/invoke cheatsheetです。

于 2012-06-01T03:53:10.050 に答える