0

I'm trying to use P/Invoke to call some functions in a third party native DLL. But I keep receiving FatalExecutionEngine error. Probably I'm making some mistake against the marshalling of data or ?

This is the native function I'm trying to use:

__declspec(dllexport) void dw_mm_directional_spectrum_initialise(
    struct dw_mm_directional_spectrum_T* directional_spectrum
    , const enum dw_buoy_type_T buoy_type
    , const unsigned char status[ /* NULL || sample_count */ ]
    , const double v[ /* sample_count */ ]
    , const double n[ /* sample_count */ ]
    , const double w[ /* sample_count */ ]
    , const unsigned int sample_count);

This is the native struct which is returned through a pointer:

struct dw_mm_directional_spectrum_T{
    signed char error_code;
    double* c_vv;
    double* c_nn;
    double* c_ww;
    double* c_nw;
    double* q_vn;
    double* q_vw;
    unsigned short output_size;
    double fraction_of_segments_used;
    unsigned char* list_of_used_segments;
    unsigned short list_of_used_segments_size;
};

This is the struct definition in the C# program:

[StructLayout(LayoutKind.Sequential)]
struct datawell{
    Byte error_code;
    double[] c_vv;
    double[] c_nn;
    double[] c_ww;
    double[] c_nw;
    double[] q_vn;
    double[] q_vw;
    ushort output_size;
    double fraction_of_segments_used;
    IntPtr list_of_used_segments;
    ushort list_of_used_segments_size;
};

My DLLimport signature:

[DllImport("libwaves.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void dw_mm_directional_spectrum_initialise(
    out datawell dw,
    Byte buoy_type,
    Byte[] status,
    double[] v,
    double[] n,
    double[] w,
    ushort sample_count);

And this is how I use the function in my C# program:

double[] vertical = new double[512]; 
double[] north = new double[512];
double[] west = new double[512];
Byte[] status = new Byte[512];
datawell dw_test = new datawell();
ushort cnt = 512;

//dummy data generation
for(int i=0;i<512;i++){
    status[i]=1;
    vertical[i]=i*1.0;
    north[i]=i*1.0;
    west[i]=i*1.0;
}

dw_mm_directional_spectrum_initialise(out dw_test,0,status, vertical, north,west,cnt);

Any help would be highly appreciated.

Regards,

Zjerre

0

2 Answers 2

2

You cannot marshal the pointers contained in the struct as C# arrays. You are going to need to declare them as IntPtr, and then marshal them yourself. You'll need Marshal.Copy() for that process.

I'm not sure about the memory ownership rules. Presumably the native code allocates the arrays that come back in the struct? If so then I guess you'll have to call the native library again when you are done with the struct so that it can deallocate the arrays.

Sign up to request clarification or add additional context in comments.

1 Comment

David thanks for your answer. You're completly right. There is a function to destroy the allocated memory which takes the returned struct as an input. After declaring the arrays as IntPtrs and marshal.copying them it working without any issues. Thanks a lot !
1

list_of_used_segments is defined as unsigned char* in C and double[] in C#.

1 Comment

SLaks, Thanks for the answer. I changed the type to IntPtr but still the same error.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.