如何封送结构的C ++ / CLI阵列非托管C ++
题
我在寻找正确的语法一个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移动你的记忆)之前将它传递给本地代码。
不隶属于 StackOverflow