Reputation: 33
I have the following C++ method :
__declspec(dllexport) void __stdcall getDoubles(int *count, double **values); the method allocates and fills an array of double and sets *count to the size of the array.
The only way i managed to get this to work via pinvoke is :
[System.Runtime.InteropServices.DllImportAttribute("xx.dll")]
public static extern void getDoubles(ref int count, ref System.IntPtr values);
and usage is :
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)));
}
the values end up in the dvs array. Is there a better way ti do this not invloving pointer arithmetic in a managed language...
Upvotes: 3
Views: 8148
Reputation: 14084
You'll need to change the unmanaged method signature so it reads like this:
__declspec(dllexport) void __stdcall getDoubles(SAFEARRAY *array);
Then you should be able to use the following managed version of the function:
[System.Runtime.InteropServices.DllImportAttribute("xx.dll")]
public static extern void getDoubles(
[MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VT_R8)]
double[] array
);
Of course that you'll also have to rewrite your unmanaged code to work with SAFEARRAYs. More about this topic can be found at MSDN.
One question though, I recall working with ZLib in C# which is able, without any wrapper, to work with byte[] while the unmanaged counterpart is BYTE*, have you tried working directly with double* / double[] ?
Upvotes: 1