我正在尝试编写一个包装器,以便我的C#应用程序可以使用用C编写的DLL。 这是我想要包装的方法定义:
void methodA(const uint32_t *data); //c header declaration
我遇到的问题是试图找出如何从c#中提供等效指针。在c#中,我希望它在:
上运行 UInt32 data[] //my c# object i want to be able to pass in
但如何在包装器中提供等效指针?我试过了
ref data //my attempt at giving an equivalent pointer to the DLL
但这似乎不起作用。在DLL中使用调试语句我可以看到它获取的值不是我试图传入的值。
所以我的问题归结为我是否正确包装了一个使用指针引用数组的c函数?
答案 0 :(得分:3)
数组已经是一个引用,因此它将被编组为指向它的指针。这应该有效:
[DllImport("my.dll")]
static extern void methodA(UInt32[] data);
如果您需要将数据传递回托管代码,则需要使用Out attribute修饰参数:
[DllImport("my.dll")]
static extern void methodA([In, Out] UInt32[] data);
用法:
uint[] data = new uint[] { 1, 2, 3, 4, 5 };
methodA(data);
Console.WriteLine(data[0]);
另一种解决方案是将参数声明为IntPtr类型:
[DllImport("my.dll")]
static extern void methodA(IntPtr data);
要使其工作,您需要固定数组以获取IntPtr,或者在非托管空间中分配内存并将数组内容复制到它。不过,我不会推荐这些选项。
ref
:
[DllImport("my.dll")]
static extern void methodB(ref UInt32 data);
答案 1 :(得分:1)
在P / Invoke声明中使用IntPtr参数声明methodA。要将UInt32数组转换为非托管数组,请使用Marshal.Copy Method (Int32[], Int32, IntPtr, Int32)。
本文中的代码示例对您来说没问题,请在此行之后调用methodA:
Marshal.Copy(managedArray, 0, pnt, managedArray.Length);
// now call methodA with pmt parameter