Как передать SAFEARRAY UDT в неповрежденный код из C # - PullRequest
3 голосов
/ 18 апреля 2010

Я также использовал VT_RECORD. Но не удалось успешно пройти безопасную проверку UDT.

        [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
        );

Если я связываюсь со своим неуправляемым кодом без 1-го параметра, то при передаче параметра "guids" в неуправляемый код не возникает ошибка.

Я также могу привести элементы полученного SAFEARRAY на неуправляемой стороне к типу GUID. Но если я попытался передать свой класс UDT MY_CLASS неуправляемому коду с помощью SAFEARRAY, то это не сработало в управляемом коде. (как указано выше фрагмент кода)

Это показывает исключение «Необработанное исключение типа« System.Runtime.InteropServices.SafeArrayTypeMismatchException »произошло в myapp.exe» «Дополнительная информация: указанный массив не соответствует ожидаемому типу.»

Пожалуйста, помогите мне в такой ситуации передать SAFEARRAY UDT в неповрежденный код.

1 Ответ

1 голос
/ 21 апреля 2010

У меня есть одно решение этой проблемы.


Я попробовал альтернативу этой проблеме. Я передал UDT с элементами SAFEARRAY в качестве неуправляемого кода.

Вот управляемый код, которому я следовал,

    [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, имеющего массив типов-значений, вместо передачи массива UDT.

...