如何将C ++ / CLI数组结构编组为非托管C ++

时间:2009-04-09 16:37:01

标签: c++ interop unmanaged managed

我正在搜索将struct数组传递给非托管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有很多有用的方法可以做这样的事情,但我不确定要使用哪种方法。

2 个答案:

答案 0 :(得分:3)

使用StructLayout.Sequential创建非托管结构的托管版本(确保以相同的顺序放置内容)。然后,您应该能够将其传递给任何托管函数(例如,验证(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();
    }

答案 1 :(得分:1)

您可以使用Marshall.StructureToPtr获取可以传递到本机MyStruct *数组的IntPtr。

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