【问题标题】:How to marshal C++/CLI array of struct to unmanaged C++如何将结构的 C++/CLI 数组编组为非托管 C++
【发布时间】:2009-04-09 16:37:00
【问题描述】:

我正在寻找将结构数组传递给非托管 C++ dll 的正确语法。

我的 dll 导入是这样调用的

    #define _DllImport [DllImport("Controller.dll", CallingConvention = CallingConvention::Cdecl)] static
_DllImport bool _Validation(/* array of struct somehow */);

在我的客户端代码中

List<MyStruct^> list;
MyObject::_Validation(/* list*/);

我知道 System::Runtime::InteropServices::Marshal 有很多有用的方法来做这样的事情,但我不知道该使用哪个。

【问题讨论】:

    标签: c++ interop unmanaged managed


    【解决方案1】:

    使用 StructLayout.Sequential 创建非托管结构的托管版本(确保以相同的顺序放置)。然后,您应该能够像将其传递给任何托管函数一样传递它(例如,Validation(MyStruct[] pStructs)。

    例如,假设我们的原生函数有这个原型:

    extern "C" {
    
    STRUCTINTEROPTEST_API int fnStructInteropTest(MYSTRUCT *pStructs, int nItems);
    
    }
    

    而原生的MYSTRUCT定义如下:

    struct MYSTRUCT
    {
        int a;
        int b;
        char c;
    };
    

    然后在 C# 中,定义结构的托管版本,如下所示:

    [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
    public struct MYSTRUCT
    {
        public int a;
        public int b;
        public byte c;
    }
    

    而托管原型如下:

        [System.Runtime.InteropServices.DllImportAttribute("StructInteropTest.dll", EntryPoint = "fnStructInteropTest")]
        public static extern int fnStructInteropTest(MYSTRUCT[] pStructs, int nItems);
    

    然后您可以调用该函数,并传递一个 MYSTRUCT 结构数组,如下所示:

        static void Main(string[] args)
        {
            MYSTRUCT[] structs = new MYSTRUCT[5];
    
            for (int i = 0; i < structs.Length; i++)
            {
                structs[i].a = i;
                structs[i].b = i + structs.Length;
                structs[i].c = (byte)(60 + i);
            }
    
            NativeMethods.fnStructInteropTest(structs, structs.Length);
    
            Console.ReadLine();
        }
    

    【讨论】:

      【解决方案2】:

      您可以使用 Marshall.StructureToPtr 获取一个 IntPtr,该 IntPtr 可以传递到本机 MyStruct* 数组中。

      但是,我不确定如何直接从列表中执行此操作。我相信您需要将其转换为数组并使用 pin_ptr(以防止 GC 移动您的内存),然后再将其传递给本机代码。

      【讨论】:

        猜你喜欢
        • 2015-10-26
        • 2012-04-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-30
        • 2017-04-24
        • 1970-01-01
        相关资源
        最近更新 更多