我在这里和这里都已经阅读了使用P / Invoke在C ++ Interop上的各种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 ++端写入数组的双打。但是,我想知道:
请注意,我们有一个可用的C ++ / Cli版本,但是第三方库代码中与本地静态变量有关的一些问题会导致崩溃。Microsoft将此问题标记为WONTFIX,这就是为什么我要寻找替代方法。
如果将确定输出长度的代码与填充输出的代码分开是可行的,则可以:
但是我假设您已经拒绝了此选项,因为它不切实际。在这种情况下,您的代码是解决问题的完全合理的方法。实际上,我会说您做得很好。
修复调用约定不匹配后,该代码在x86中将完全相同。在C ++方面,调用约定是cdecl
,但在C#方面是stdcall
。在x64上这无关紧要,因为只有一种调用约定。但这在x86下是个问题。
一些评论:
[Out]
以及out
。后者意味着前者。CoTaskMemAlloc
在C ++方面,然后Mashal.FreeCoTaskMem
在C#方面进行释放。本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句