如何解决C ++与C#的DLL互操作:公开未知大小的多维数组,以及内存管理
| 我有一个C ++库,可以执行一些核心财务数学(Quantlib)。我有一个针对它构建的普通C ++ dll,它向C#前端应用程序公开了一个轻量级接口,以允许用户传递各种参数,运行方案等。然后该dll返回数据以供显示。 我真的不清楚如何处理dll和C#层之间的接口,但是特别是我不知道在哪里处理内存分配/释放,即在C#或dll中 本质上,我希望我的dll返回一个包含二维值数组(double,char *等)的类或结构。我在调用dll时不知道该数组的大小,所以我猜它必须由dll本身分配。 目前,我的dll返回了一个以管道分隔的值列表的looooooooong char *。这似乎可行,但它并不是给我一个特别优雅的解决方案。 大家有帮助吗? 编辑 非常感谢您的所有反馈。抱歉,多年来我都没有进行过任何DLL编程,因此这是一个愚蠢的问题。 我决定将2d数组简单地视为在C ++一侧具有高度/宽度偏移的1d数组,并且只需要猜测数组的大小即可。在C#端创建一个2d数组,并以这种方式将其编组到C ++似乎正常。 这就是我所拥有的。有什么想法吗? C#: [DllImport(<dllPath>,CallingConvention = CallingConvention.Cdecl)]
static extern void ChangeArray2d(double[,] arr,int l1,int l2);
//populated with some sample values
double[,] arr = new double[,] { { 1,2,3,4 },{ 5,6,7,8 } };
ChangeArray2d(arr,arr.GetLength(0),arr.GetLength(1));
C ++:
__declspec(dllexport) void ChangeArray2d( double* arrayin,int height,int width)
{
for (int n = 0; n<height; n++){
for (int m = 0; m<width; m++){
arrayin[n*width+m] = arrayin[n*width+m] + 100;
}
};
return;
}
解决方法
通常,分配缓冲区,将其(缓冲区大小作为一次可以处理的最大数据量)传递给C ++本机函数(将填充它,然后处理数据/空闲缓冲区)是一种常见的模式。或重用缓冲区。
如果您的本机函数为您分配了缓冲区,则应在以后释放它-这是易碎的合同,并且还禁止内存重用。例如。如果您需要调用此函数20次-您将有20个不必要的分配。
像这样:
private int YourNativeFunctionStub(IntPtr buffer,int bufferSize)
{
int writtenToBufferBytes = bufferSize; // if it wrote less to buffer - it should return correct count of bytes
// here your library fills the buffer with data
return writtenToBufferBytes;
}
private double[] GetArrayFromNative()
{
int bufsize = 1024; // probably you should find it by calling another func from your library?
IntPtr nativeBuffer = Marshal.AllocHGlobal(bufsize);
try
{
int bytesReceivedInBuffer = YourNativeFunctionStub(nativeBuffer,bufsize);
int receivedArrayLength = bytesReceivedInBuffer / sizeof(double);
var managedArray = new double[receivedArrayLength];
Marshal.Copy(nativeBuffer,managedArray,receivedArrayLength);
return managedArray;
}
finally
{
Marshal.FreeHGlobal(nativeBuffer);
}
}
UPD:请参阅Hans的评论。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。