zohar
zohar

Reputation: 33

Returning a variable sized array of doubles from C++ to C# - a simpler way?

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

Answers (2)

arul
arul

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

Ahmed
Ahmed

Reputation: 7238

I think you can use

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

Upvotes: 3

Related Questions