3

VT_RECORD も使用しました。しかし、UDT の safearray を渡すことに成功しませんでした。

        [ComVisible(true)]
        [StructLayout(LayoutKind.Sequential)]
        public class MY_CLASS
        {
            [MarshalAs(UnmanagedType.U4)]
            public Int32 width;
            [MarshalAs(UnmanagedType.U4)]
            public Int32 height;
        };

    [DllImport("mydll.dll")]
    public static extern Int32 GetTypes(
        [In, Out][MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_RECORD, SafeArrayUserDefinedSubType = typeof(MY_CLASS))]MY_CLASS[] myClass,
        [In, Out][MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_RECORD, SafeArrayUserDefinedSubType = typeof(Guid))]Guid[] guids
        );

最初のパラメーターを使用せずにアンマネージ コードと通信すると、「guids」パラメーターをアンマネージ コードに渡してもエラーは発生しません。

アンマネージ側で取得した SAFEARRAY の要素を GUID 型にキャストすることもできました。しかし、UDT クラス MY_CLASS を SAFEARRAY を使用してアンマネージ コードに渡そうとすると、マネージ コードで失敗します。(上記のコード スニペットのように)

「タイプ 'System.Runtime.InteropServices.SafeArrayTypeMismatchException' の未処理の例外が myapp.exe で発生しました」「追加情報: 指定された配列は予期されたタイプではありませんでした」という例外が表示されます。

このような状況で UDT の SAFEARRAY を unmaged コードに渡すのを手伝ってください。

4

1 に答える 1

1

この問題の解決策が 1 つあります。


この問題の代替案を試しました。SAFEARRAY をメンバーとして持つ UDT をアンマネージ コードに渡しました。

これが私が従ったマネージドコードです。

    [ComVisible(true)]
    [StructLayout(LayoutKind.Sequential)]
    public class MY_CLASS
    {
        [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.I4)]
        public Int32[] width;
        [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.I4)]
        public Int32[] height;
    };

    [DllImport("mydll.dll")]
    public static extern Int32 GetTypes(
        [In, Out] MY_CLASS myClass
        );

管理されていない側では、

    typedef struct _MY_STRUCT
    {
        SAFEARRAY * pWidths;
        SAFEARRAY * pHeights;
    }MY_STRUCT;

    HRESULT GetTypes(MY_STRUCT * pMyStruct)
    {
        // Here I can use pMyStruct->pWidths or pMyStruct->pHeights
        //      paramater as safearray of int32 type.
        // I can modify it's element and it will be visible
        //      on managed side.

        return S_OK;
    }

このタイプのメカニズムを使用して、UDT の配列を渡す代わりに、Value-Type の配列を持つ UDT を渡します。

于 2010-04-21T10:08:55.723 に答える