Float * C to C #

I'm not really a CS guy, so if any of you geniuses can point me in the right direction, I will be eternally grateful.

I have a c-code command line function that I used to write my results to a file. I converted it to return data using the float * array to the same C ++ program (to avoid constant file I / O):

float * mgrib(int argc, char **argv) 

It worked perfectly. Now I need to get this in a C # program, and here, where it all went.

The first thing I did to avoid char ** was to make the arguments a bool series. This worked fine if I let it still dump files.

The problem is juggling with a float c-style array in C #. Inside the c code, it was assigned using malloc.

So, all that I tried without success (I know the size of the array):

  • Make a β€œfree” export function for calling from C # to free up memory when I am done with it. After several cycles, C # crashes without warning.

  • Release malloc with C # using Marshal.FreeCoTaskMem. The same result.

  • Move float * to the argument and remove the c-code malloc. (void mgrib (..., float * data, ...)

__ a) Highlight it using Marshal.AllocCoTaskMem. Free it with Marshal.FreeCoTaskMem.

__ b) Use Marshal.Copy to highlight. Free it with Marshal.FreeCoTaskMem (maybe this is wrong?)

I did almost everything I could find on the Internet. Please let me know if more information is needed. I hope this is just a simple concept that I am missing.

+6
c pointers c # malloc marshalling
source share
1 answer

Use this signature for your C function (replace mgrib.dll with the real library name).

 [DllImport( "mgrib.dll", EntryPoint = "mgrib" )] public static extern IntPtr mgrib( int argc, [MarshalAs( UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr )] StringBuilder[] argv ); 

Call the mgrib function as follows:

 // Prepare arguments in proper manner int argc = 0; StringBuilder[] argv = new StringBuilder[ argc ]; IntPtr pointer = mgrib( argc, argv ); 

When the call is completed, you can get the result as follows:

 float[] result = new float[ size ]; Marshal.Copy( pointer, result, 0, size ); 

EDIT

Since mgrib allocates memory using malloc , we need to free memory using the free function. However, you will have to transfer the call to the free function to another function that will be exported from the native library.

 extern "C" __declspec(dllexport) void mgrib_free( float* pointer ); void mgrib_free( float* pointer ) { free( result ); } 

And then import it like this:

 [DllImport( "mgrib.dll", EntryPoint = "mgrib_free", CallingConvention = CallingConvention.Cdecl )] public static extern void mgrib_free( IntPtr pointer ); 

And call it like this:

 mgrib_free( pointer ); 
+4
source share

All Articles