【发布时间】:2014-02-03 23:17:53
【问题描述】:
我已经阅读了有关 C++ Interop 与 P/Invoke here 和 here 的各种 MSDN 页面,但我仍然感到困惑。
我有一些大型双精度数组需要进入本机代码,以及一些需要返回的结果数组。我事先不知道输出数组的大小。为简单起见,我将在示例中仅使用一个数组。平台为x64;我读到 32 位和 64 位环境之间的编组内部结构完全不同,所以这可能很重要。
C#
[DllImport("NativeLib.dll")]
public static extern void ComputeSomething(double[] inputs, int inlen,
[Out] out IntPtr outputs, [Out] out int outlen);
[DllImport("NativeLib.dll")]
public static extern void FreeArray(IntPtr outputs);
public void Compute(double[] inputs, out double[] outputs)
{
IntPtr output_ptr;
int outlen;
ComputeSomething(inputs, inputs.Length, out output_ptr, out outlen);
outputs = new double[outlen];
Marshal.Copy(output_ptr, outputs, 0, outlen);
FreeArray(output_ptr);
}
C++
extern "C"
{
void ComputeSomething(double* inputs, int input_length,
double** outputs, int* output_length)
{
//...
*output_length = ...;
*outputs = new double[output_length];
//...
}
void FreeArray(double* outputs)
{
delete[] outputs;
}
}
它可以工作,也就是说,我可以读出我在 C++ 端写入数组的双精度数。但是,我想知道:
- 这真的是使用 P/Invoke 的正确方法吗?
- 我的签名不是不必要的复杂吗?
- 能否更有效地使用 P/Invoke 来解决此问题?
- 我相信我读过可以避免对内置类型的一维数组进行编组。有没有办法绕过 Marshal.Copy?
请注意,我们有一个可用的 C++/Cli 版本,但第三方库代码中存在一些与本地静态相关的问题,这些问题会导致崩溃。 Microsoft marked this issue as WONTFIX,这就是我寻找替代品的原因。
【问题讨论】:
标签: c# c++ interop pinvoke marshalling