gpt4 book ai didi

c# - C++ DLL 与 C# : Exposing multidimensional arrays of unknown size, 和内存管理互操作

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:58:21 25 4
gpt4 key购买 nike

我有一个 C++ 库,可以执行一些核心金融数学 (Quantlib)。我有一个针对它构建的普通 C++ dll,它向 C# 前端应用程序公开一个轻量级接口(interface),以允许用户传入各种参数、运行场景等。dll 然后返回数据以供显示。

不过,我真的不清楚如何处理 dll 和 C# 层之间的接口(interface),特别是我不知道内存分配/解除分配是在哪里处理的,即在 C# 或 dll 中

本质上,我希望我的 dll 返回一个包含二维值数组(double、char* 等)的类或结构。我在调用 dll 时不知道该数组的大小,所以我猜它必须由 dll 本身分配。

此刻,我让 dll 返回一个 looooooooong char* 和一个以竖线分隔的值列表。这似乎可行,但它并不是一个特别优雅的解决方案。

有什么帮助吗,伙计们?

编辑

非常感谢您的所有反馈。抱歉,我已经很多年没有做过任何 DLL 编程了,所以提出了一个有点愚蠢的问题。

我决定将二维数组简单地视为在 C++ 端具有高度/宽度偏移量的一维数组,并且只接受预先猜测数组的大小。在 C# 端创建一个二维数组,并以这种方式将其编码到 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++ native 函数,然后处理数据/空闲缓冲区。或者重复使用缓冲区。

如果您的 native 函数为您分配缓冲区并且您应该在之后释放它 - 它是可变的脆弱契约并且还禁止内存重用。例如。如果您需要调用此函数 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, 0, receivedArrayLength);
return managedArray;
}
finally
{
Marshal.FreeHGlobal(nativeBuffer);
}
}

UPD:查看 Hans 的评论。

关于c# - C++ DLL 与 C# : Exposing multidimensional arrays of unknown size, 和内存管理互操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6395305/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com