在托管代码中填充非托管数组

Posted

技术标签:

【中文标题】在托管代码中填充非托管数组【英文标题】:Filling unmanaged array in managed code 【发布时间】:2011-09-19 11:18:34 【问题描述】:

我有一个托管程序,它与非托管 DLL 库配合使用。

Library 构造一个对象,该对象要求(通过转换为委托的回调函数)托管主机填充非托管数组。数组本身通过指针 (IntPtr) 以及有关其大小的信息传递。这种类型是双方都知道的。关键是,如何安全地用托管代码中的数据填充非托管数组?有两个限制:没有不安全的代码,最好没有创建额外的数组。如果存在,则数组可能会以另一种方式传递。

让回调有如下原型:

typedef void (__stdcall * FillData)(double * array, int count);

让委托有以下原型:

protected delegate void FillData(IntPtr array, int count);

【问题讨论】:

可以分享callback的签名吗? 按要求添加回调签名。 什么是 PInvoke 等价物;你用的是什么? 【参考方案1】:

如果您不想要不安全的代码,那么您必须让 pinvoke marshaller 复制数组。像这样声明委托类型:

private delegate MyUnmanagedCallback(
     [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] double[] array,
     int count);

请务必存储委托对象,使其不会被垃圾回收。

【讨论】:

【参考方案2】:

根据您的 FillData 原型编写托管回调。使用 Marshal.GetFunctionPointerForDelegate 方法从中创建非托管函数指针。将其作为回调函数指针传递给非托管代码。

【讨论】:

我正在这样做。问题是,如何将数组从非托管代码传递到托管代码,以便托管可以用数据填充它。

以上是关于在托管代码中填充非托管数组的主要内容,如果未能解决你的问题,请参考以下文章

将多维数组从托管代码传递到非托管代码

如何在托管 (C#) 和非托管 (C++) 代码之间来回传递数组内容

在 C# 中传递 IntPtr 指针后,在非托管 C++ 代码中分配数组,编组类型

使用 ATL/COM 将托管字节 [] 转换为非托管字节数组

非托管 C++ 代码向托管代码发送字符串的错误

C# 托管非托管代码