我在寻找正确的语法一个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*/);

我知道系统:运行:: InteropServices ::元帅有很多做这样的东西有用的方法,但我不知道用哪个。

有帮助吗?

解决方案

创建使用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();
    }

其他提示

可以使用 Marshall.StructureToPtr 以获得其可通入天然MYSTRUCT *阵列一个IntPtr。

不过,我不知道如何从列表中直接做到这一点。我相信你需要将其转换为一个数组,并使用pin_ptr(防止GC移动你的记忆)之前将它传递给本地代码。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top