从C ++返回一个可变大小的双精度数组到C# - 一种更简单的方法?

时间:2009-01-14 11:57:13

标签: c# c++ arrays pinvoke

我有以下C ++方法:

__ declspec(dllexport)void __stdcall getDoubles(int * count,double ** values); 该方法分配并填充double数组,并将* count设置为数组的大小。

我通过pinvoke设法让这个工作的唯一方法是:

[System.Runtime.InteropServices.DllImportAttribute("xx.dll")]
 public static extern void getDoubles(ref int count, ref System.IntPtr values);

用法是:

int count = 0;
IntPtr doubles = new IntPtr();
Nappy.getDoubles(ref count, ref doubles);
double[] dvs = new double[count];
for(int i = 0;i < count;++{
    dvs[i] = (double)Marshal.PtrToStructure(doubles, typeof(System.Double));
    doubles = new IntPtr(doubles.ToInt64()+Marshal.SizeOf(typeof(System.Double)));
}

值最终在dvs数组中。 有没有更好的方法来执行此操作而不是在托管语言中使用指针算法...

2 个答案:

答案 0 :(得分:2)

我认为你可以使用

Marshal.Copy( source, destination, 0, size );

答案 1 :(得分:1)

您需要更改非托管方法签名,使其如下所示:

__declspec(dllexport) void __stdcall getDoubles(SAFEARRAY *array); 

然后您应该能够使用以下托管版本的功能:

[System.Runtime.InteropServices.DllImportAttribute("xx.dll")]
public static extern void getDoubles(
              [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VT_R8)]
              double[] array
);

当然,您还必须重写非托管代码才能使用SAFEARRAY。 有关此主题的更多信息can be found at MSDN.

但是有一个问题,我记得在C#中使用ZLib可以在没有任何包装器的情况下使用byte [],而非托管对应物是BYTE *,你是否尝试直接使用double * / double []?