1

私のアプリケーションでは、P/Invokeを使用して絶対に任意のオブジェクト/構造体をC++関数に渡す必要があります。インターネットによると、任意のオブジェクトはC ++構造体として渡される可能性があります(呼び出しの間、オブジェクトは特定のメモリ位置に固定されます)。私はデータにのみ興味があり、メソッドを呼び出す予定はないので、これは私のニーズに十分に一致します。ただし、実験では、これらのオブジェクトには[StructLayout(LayoutKind.Sequential)]属性が必要であることが示されています。そうでない場合、コードはコンパイルされません。残念ながら、クラスは他の開発者によって作成されており、この属性を持つことが保証されていません。

この問題を解決するための1つの解決策は、オブジェクトを特別なC#ラッパー関数に渡すことです。

  1. を使用してオブジェクトのプロパティを取得するType.GetProperties
  2. 必要なプロパティを使用して構造体を動的に作成し、オブジェクトから値をコピーします。
  3. 属性を追加[StructLayout(LayoutKind.Sequential)]します。
  4. この構造体を、ステップ1で取得したメタデータとともにC ++に渡します(C ++がオブジェクト構造とその読み取り方法を認識できるようにするため)

私はC#を初めて使用するため、任意のプロパティと属性を使用して構造体を動的に作成する方法がわかりません。これまでに見つけたのはMakeGenericTypeExpandoObjectですが、必要なのは、以前はどこにも定義されていなかった動的構造体を作成することです。ジェネリックオブジェクトとしても定義されていません。何か案は?

4

1 に答える 1

1

このようなものはあなたのために働くことができますか?

    [StructLayout(LayoutKind.Sequential)]
    struct MyStruct
    {
        public int Size;
        public IntPtr PtrToArrayOfMetadata;
        public IntPtr PtrToArrayOfObjects;
    }

    public enum Type
    {
        Int, 
        Float,
        Decimal
    }

そして、「動的」オブジェクトを送信します

        Type[] metadata = new Type[2];
        metadata[0] = Type.Int;
        metadata[1] = Type.Float;

        object[] obj = new object[2];
        obj[0] = 2;
        obj[1]= 1;

        GCHandle objHandle = GCHandle.Alloc(obj, GCHandleType.WeakTrackResurrection);
        IntPtr ptrObj = GCHandle.ToIntPtr(objHandle);

        objHandle = GCHandle.Alloc(metadata, GCHandleType.WeakTrackResurrection);
        IntPtr ptrMeta = GCHandle.ToIntPtr(objHandle);

        MyStruct tmp = new MyStruct();
        tmp.Size = 2;
        tmp.PtrToArrayOfMetadata = ptrMeta;
        tmp.PtrToArrayOfObjects = ptrObj;
于 2013-02-26T10:51:28.110 に答える