How can I change my C ++ code to use as a DLL in C #?

I am learning how to call methods in C ++ with C #. I did some research and it seems Pinvoke is a great way.

How can I translate this simple C ++ code the way it should be in order to be called in C #, and how can I write methods that will be called in C #?

I have a header file:

MathFuncsLib.h

namespace MathFuncs { class MyMathFuncs { public: double Add(double a, double b); MyMathFuncs getClass(); }; } 

MathFuncsLib.cpp

 #include "MathFuncsLib.h" namespace MathFuncs { MyMathFuncs MyMathFuncs::getClass() { return *(new MyMathFuncs()); } double MyMathFuncs::Add(double a, double b) { return a + b; } } 

In C #,

I would like to:

 main() { MyMathFuncs abd = MyMathFuncs::getClass(); abd.Add(1.2, 2.3); } 

I have no idea how this should be achieved, so I think it's better to ask about it.

+4
source share
4 answers

P / Invoke is more suitable when you have many static functions. Instead, you can use the C ++ / CLI , which is more appropriate if you have a set of C ++ classes or a class hierarchy of structured scope. So you can do this with your sample:

.H:

 namespace MathFuncs { public ref class MyMathFuncs { public: double Add(double a, double b); }; } 

.CPP:

 namespace MathFuncs { double MyMathFuncs::Add(double a, double b) { return a + b; } } 

.CS:

 static class Program { static void Main() { MyMathFuncs abd = new MyMathFuncs(); abd.Add(1.2, 2.3); } } 

As you can see, you do not need the getClass function, as with C ++ / CLI, your MathFuncs class becomes a full-blown .NET class.

EDIT: if you want the actual calculation (a + b in the sample) to happen in unmanaged code, you can do it like this: for example:

.H:

 namespace MathFuncs { public ref class MyMathFuncs { public: double Add(double a, double b); }; class MyMathFuncsImpl { public: double Add(double a, double b); }; } 

.CPP:

 namespace MathFuncs { double MyMathFuncs::Add(double a, double b) { MyMathFuncsImpl *p = new MyMathFuncsImpl(); double sum = p->Add(a, b); delete p; return sum; } #pragma managed(push, off) double MyMathFuncsImpl::Add(double a, double b) { return a + b; } #pragma managed(pop) } 

In this case, MyMathFuncsImpl :: Add is generated as native code, and not as IL (the call from C # is the same). See Here, Managed, Unmanaged for more information on how to mix managed and unmanaged code.

+7
source

You do not need to use the get class if the yor constructor is not private. If it is publicly available, use it as:

 main() { MyMathFuncs abd = new MyMathFuncs(); abd.Add(1.2,2.3); } 

If you want your constructor to be private, and use getClass to get an instance of your class, you must make this method static, for example:

 namespace MathFuncs { class MyMathFuncs { public double Add(double a, double b); static MyMathFuncs getClass() { return new MyMathFuncs(); } }; } 
0
source

Add a wrapper class around your specific class in C ++ / cli or C ++ managed. This is similar to a layer that can directly bind to both C ++ and C #

0
source

Using Microsoft Visual Studio (Express), I created the class as normal (without the main() function, of course), but you can choose to compile as .dll . The advantage is that the class will be in a separate file that can be reused / called from other applications that you are developing.

0
source

Source: https://habr.com/ru/post/1389454/


All Articles