【发布时间】:2021-06-25 05:13:25
【问题描述】:
我想从 C++ 中获取双精度数组。
我用整数数组进行了测试,它工作正常,但我不知道双精度数组不能工作。
双精度数组的第一个和第二个元素是错误的。
还有一个奇怪的地方,我把FreeCoTaskMem注释掉了,因为不注释的话应用会崩溃,int和double是一样的。
任何提示,谢谢。
C/C++ 代码
#define DllExport __declspec(dllexport)
extern "C"
{
DllExport void TestOutOfInts(int** ints);
DllExport void TestOutOfDoubles(double** doubles);
}
DllExport void TestOutOfInts(int** ints)
{
int xyzs[9] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
(*ints) = xyzs;
}
DllExport void TestOutOfDoubles(double** doubles)
{
double xyzs[9] = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9 };
(*doubles) = xyzs;
}
C#代码
[DllImport("MeshToolsWrapper.dll")]
static extern void TestOutOfInts(out IntPtr ints);
[DllImport("MeshToolsWrapper.dll")]
static extern void TestOutOfDoubles(out IntPtr doubles);
TestOutOfInts(out IntPtr ints);
int[] test1 = new int[9];
Marshal.Copy(ints, test1, 0, 9);
//Marshal.FreeCoTaskMem(ints);
TestOutOfDoubles(out IntPtr doubles);
double[] test2 = new double[9];
Marshal.Copy(doubles, test2, 0, 9);
//Marshal.FreeCoTaskMem(doubles);
C# 结果
# ints
1
2
3
4
5
6
7
8
9
# doubles
1.16501519399776E-311
6.95245618745976E-310
3.3
4.4
5.5
6.6
7.7
8.8
9.9
【问题讨论】:
-
两个数组都是本地的。整数一是偶然的。
-
让 C# 传递数组以供 C++ 填充。这样 C# 拥有内存(编辑:我的意思是 C# 负责保留/分配和释放/解除分配,我请您记住哪个运行时有垃圾收集器),而 C++ 只是借用。
-
啊,原来如此,难怪,非常感谢大家。
-
嗯……您可能在这里得出错误的结论。垃圾收集器没有错。正如公认的答案所提到的,数组在堆栈中分配,因此在函数返回时它被释放。不涉及垃圾收集器。您可以让 C++ 拥有内存,例如通过使用 new 分配,但是您需要记住告诉 C++ 去分配。但是,.NET 有一个垃圾收集器,这使得 C# 可以方便地拥有内存。此外,当调用者拥有内存时,通常更容易跟踪内存是否仍然有效。
-
您可能还想将调用约定设置为
Cdecl