Introducing Unmanaged C ++ Functions from C #

I have standard ANSI C code that is authoritative. This means that although I have a source, I cannot translate into another language and not change the arguments of the call, since these actions will deprive the right. There are over 150 functions.

I can make random changes, for example, change the file names from .C to .CPP so that it compiles using the Visual Studio 2009 C ++ compiler that I made. Compiler directives can also be added, etc. I can also go through the shell layer if necessary.

Another limitation is that my company does not want me to use the unsafe keyword in any C # code.

I need to get these functions from a C # program.

A typical C / C ++ function is as follows:
double SomeFunction(double a, double[3] vec, double[3][3] mat);
Where the contents of the array are sometimes entered, sometimes, and, as a rule, both are displayed.

I first tried making an unmanaged DLL (with functions marked with Extern C). Functions with only simple arguments (int, double) worked fine, but I couldn't figure out how to marshal arrays. (In fact, I found some sample code, but it was extremely difficult and unreasonable to duplicate 150 times.)

Then I tried two projects in one solution, one in C ++ and the other in C #. In a C ++ project, I created a managed function that was just called the original function, which was marked as unmanaged. It was very clean and simple, and again simple arguments worked perfectly. But for arrays, I could not find a way to match argument types between C # and C ++ borders:
Argument '2': cannot convert from 'double[]' to 'double*'
(and, as mentioned above, I cannot use unsafe to get a pointer).

Of course, what I'm trying to do should be possible.
What is the best way to get these features?
(Sample code using the above function will be really cool.)

+4
source share
3 answers

C / C ++ implementation example:

 extern "C" __declspec(dllexport) double SomeFunction(double a, double vec[3], double mat[3][3]) { double sum = a; for (int ix = 0; ix < 3; ++ix) { sum += vec[ix]; for (int iy = 0; iy < 3; ++iy) { sum += mat[ix][iy]; } } return sum; } 

C # usage example:

 private void Form1_Load(object sender, EventArgs e) { double[] vec = new double[3]; double[,] mat = new double[3, 3]; for (int ix = 0; ix < 3; ++ix) { vec[ix] = ix; for (int iy = 0; iy < 3; ++iy) { mat[ix, iy] = (ix + 1) * iy; } } double sum = SomeFunction(1, vec, mat); } [System.Runtime.InteropServices.DllImport("cpptemp8.dll")] private static extern double SomeFunction(double a, double[] vec, double[,] mat); 
+4
source

If you can't get extern and P / Invoke to work, a wrapper is probably your best bet. Create a managed C ++ DLL that uses both managed and unmanaged code. Add a .NET class to this DLL, which is just a thin shell over the functions in your DLL. Your C # code can call the C ++ .NET class, which in turn will continue to function C.

This way you can write the translation between .NET and unmanaged code yourself, instead of relying on runtime to do this for you.

+1
source

use swig, it will generate your pinvoke for you

0
source

All Articles