views:

50

answers:

2

Im using an P/invoke on an unmanaged dll function swe_calc_ut.

int swe_calc_ut(double tjd_et, int ipl, int iflag, double *xx, char *serr)

Parameter xx is meant to be an "array of 6 doubles for storing the result", and parameter serr a "character string to return error messages"


my c# code is as follows.

[DllImport("swedll32.dll")]
private static extern int swe_calc_ut(double tjd_ut, int ipl, int iflag, out double[] xx, out char[] serr);

double jul_day_UT=22000;
int p=3;
int iflag=64 * 1024;
double[] arr;
char[] serr;

int x = swe_calc_ut(jul_day_UT, p, iflag , out arr, out serr);

Now when i execute the function swe_calc_ut function i get the error "Exception of type 'System.ExecutionEngineException' was thrown.". I'm new to P/invoke so i'm probably making a stupid mistake. I thought it must be the arrays since earlier when i passed them by value accidentally i did not get an error. I'd really appreciate your help.

+2  A: 

You don't have to use out or ref here. In fact, lose both of them. And preallocate both arrays to the desired size in C#.

leppie
+1  A: 

It is a convention of the C language, you pass an array by passing a pointer to the first element of the array. So a double[] is already marshaled as a double*. When you use the out or ref keyword, you tell the marshaller that the function returns a pointer to a new array, a double**.

The function does not create a new array, it requires the client to pass an array that's large enough to receive the result. Therefore, neither the out nor the ref annotation is correct. The serr argument should be declared as StringBuilder btw.

The function is very dangerous since there is no way for the client to say how large an array it created. Particularly a problem with the serr argument. A detailed error message is prone to overrun the end of the array and that will destroy the garbage collected heap. Nothing you can do but pass a very large array (i.e. StringBuilder with a large Capacity) and keep your fingers crossed. Buffer overruns are the preferred attack vector for malware authors. Not likely to be abused in a managed program, it will just crash the app with FEEE.

Hans Passant