3

我还使用了 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
        );

如果我在没有第一个参数的情况下与我的非托管代码进行通信,那么将“guids”参数传递给非托管代码就没有错误。

我还能够将在非托管端获得的 SAFEARRAY 元素转换为 GUID 类型。但是,如果我尝试使用 SAFEARRAY 将我的 UDT 类 MY_CLASS 传递给非托管代码,那么它在托管代码上会失败。(如上面的代码片段)

它显示异常“myapp.exe 中发生‘System.Runtime.InteropServices.SafeArrayTypeMismatchException’类型的未处理异常”“附加信息:指定的数组不是预期的类型。”

请在这种情况下帮助我将 UDT 的 SAFEARRAY 传递给未加密的代码。

4

1 回答 1

1

我有一个解决这个问题的方法。


我尝试了这个问题的替代方案。我将具有 SAFEARRAYs 作为其成员的 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,而不是传递 UDT 数组。

于 2010-04-21T10:08:55.723 回答