Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

float* from C to C#

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

I have a c-code command line function that used to write its results to file. I converted it to return it's data via a float* array to a C++ program like such (to avoid constant file I/O):

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

This worked perfectly. I now need to get this into a C# program, and here's where things go haywire.

The first thing I did to avoid the char ** was to make the arguments a series of bool. That worked fine if I allow it to still dump to file.

The problem is juggling the c-style float array in C#. Within the c-code it was allocated with malloc.

So here's everything I've tried with no success(I know the size of the array):

  1. Make a "free" function to export to call from C# to release the memory when I'm done with it. After a few loops the C# crashes with no warning.

  2. Release the malloc from C# with Marshal.FreeCoTaskMem. Same result.

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

__a)Allocate it with Marshal.AllocCoTaskMem. Free it with Marshal.FreeCoTaskMem.

__b)Use Marshal.Copy to allocate. Free it with Marshal.FreeCoTaskMem (Maybe this is wrong?)

I've dabbled in just about everything I could find in the internet. Please let me know if more info is necessary. I'm hoping this just a simple concept that I'm missing.

like image 875
Anthony Avatar asked Mar 08 '11 18:03

Anthony


People also ask

What is float * in c?

Float is a datatype which is used to represent the floating point numbers. It is a 32-bit IEEE 754 single precision floating point number ( 1-bit for the sign, 8-bit for exponent, 23*-bit for the value. It has 6 decimal digits of precision.

Can we use %d for float in c?

So, you can see here that %d is used for integers, %f for floats and %c for characters. As simple as that! %. 2f means that the variable to be printed will be of type float and '.

What is double float in c?

A double type variable is a 64-bit floating data type C, C++, C# and many other programming languages recognize the double as a type. A double type can represent fractional as well as whole values. It can contain up to 15 digits in total, including those before and after the decimal point.

Is float function in c?

C, C++, C# and many other programming languages recognize float as a data type. Other common data types include int and double. The float type can represent values ranging from approximately 1.5 x 10-45 to 3.4 x 1038, with a precision — the limit of digits — of seven.


Video Answer


1 Answers

Use this signature for your C function (replace the mgrib.dll with 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 done, you can get the result like this:

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

EDIT:

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

extern "C" __declspec(dllexport) void mgrib_free( float* pointer );

void mgrib_free( float* pointer )
{
    free( result );
}

And then import it into like this:

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

And invoke it as follows:

mgrib_free( pointer );
like image 85
Rest Wing Avatar answered Sep 25 '22 20:09

Rest Wing