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):
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.
Release the malloc from C# with Marshal.FreeCoTaskMem. Same result.
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.
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.
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 '.
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.
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.
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 );
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With