Answered FatalExecutionEngineError using a dll

Maylar

Member
Joined
Jan 22, 2021
Messages
18
Programming Experience
10+
I have a third party dll that I want to use in a C# application. I have sample code in C++ including the function declarations and I've created a console application, modified with (I think) equivalent data types and my homegrown printf(). When I run the application it chokes at the first function call with a fatal exception,

FatalExecutionEngineError occurred
Cannot evaluate expression because a native frame is on top of the call stack.

The original prototype for the function is this

function declaration C++:
void __cdecl C_lin_coeff_batch(double z[], int32_t z_fpp, double theta[],
                               int32_t C_in[], bool inverse, int32_t C_fpp,
                               int32_t C_int_fpp, uint16_t method, int32_t
                               ci_mean_sel, double cc[], uint32_t cc_fpp[],
                               int32_t ccx[], double cci[], double best_fit[],
                               uint32_t cn_div[], uint32_t cn_shift[],
                               uint32_t n_samples, int32_t n_sample_x_devices,
                               int32_t n_cc, int32_t n_cn_div, int32_t n_cn_shift);

Which I translated to this

C# Dllimport:
[DllImport("linearize_r01.dll")]
        public static extern void c_lin_coeff_dut(Int32[] C_in, double[] z, double[] theta,
        Int32 C_fpp, Int32 C_int_fpp, Int32 z_fpp, int inverse,
        ref double[] cc, ref UInt32[] cc_fpp, ref Int32[] ccx, ref double[] cci,
        ref double[] error_vs_z, ref UInt32[] cn_div, ref Int32[] cn_shift,
        Int32 n_samples, Int32 n_cc, Int32 n_cn_div, Int32 n_cn_shift);

Can anyone give me directions to get this to work?

Thanks

Dave
 
Solution
I assume there is a reason why some of the arrays are declared as ref while others are not.

Anyway, I would first start off by trying to match the calling convention. The DllImport attribute takes a calling convention. You probably should pass in the fact that the function is a C calling convention instead of the StdCall or WinApi calling convention that C# normally expects.
Are you sure you posted the right functions? The C function looks to be named C_lin_coeff_batch, but the P/Invoke declaration you posted is for c_lin_coeff_dut. Furthermore, the C function's parameters starts off with an array of doubles, but your P/Invoke starts off with an array of Int32s.
 
Are you sure you posted the right functions? The C function looks to be named C_lin_coeff_batch, but the P/Invoke declaration you posted is for c_lin_coeff_dut. Furthermore, the C function's parameters starts off with an array of doubles, but your P/Invoke starts off with an array of Int32s.
Oops, my bad. I copied the wrong declaration from the C++ header. This is the original prototype that I'm attempting to duplicate:

c_lin_coeff_dut, C++ version:
void __cdecl c_lin_coeff_dut(int32_t C_in[], double z[], double theta[],
        int32_t C_fpp, int32_t C_int_fpp, int32_t z_fpp, int inverse,
        double cc[], uint32_t cc_fpp[], int32_t ccx[], double cci[],
        double error_vs_z[], uint32_t cn_div[], int32_t cn_shift[],
        int32_t n_samples, int32_t n_cc, int32_t n_cn_div, int32_t n_cn_shift);
 
I assume there is a reason why some of the arrays are declared as ref while others are not.

Anyway, I would first start off by trying to match the calling convention. The DllImport attribute takes a calling convention. You probably should pass in the fact that the function is a C calling convention instead of the StdCall or WinApi calling convention that C# normally expects.
 
Solution
Thank you very much. I added the calling convention CallingConvention.Cdecl and eliminated the ref keywords and the code no longer crashes. I had assumed that any output parameters should be declared as ref or out per C# convention. I guess arrays are passed by reference anyway so it doesn't matter.

Thanks again.

Dave
 
Back
Top Bottom