简体   繁体   中英

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

I am learning how to call methods in C++ from C#. I have done some research and it seems Pinvoke is a nice way.

How can I translate this simple C++ code to the way how it should be in order to be called in C#, and how can I write the methods to 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 have:

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

I have no clue how it should be achieved, so I think it is better to ask about it.

P/Invoke is more suited when you have a lot of static functions. You could instead use C++/CLI , which is more appropriate when you have a set of C++ classes, or a structured domain model hierarchy of classes. This is how you could do it with your sample:

The .H:

namespace MathFuncs {

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

The .CPP:

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

The .CS:

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

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

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

The .H:

namespace MathFuncs {

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

    class MyMathFuncsImpl
    {
        public:            
            double Add(double a, double b);
    };
}

The .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, not as IL (calling from C# is the same). See here: managed, unmanaged for more on how to mix managed and unmanaged code.

You don't need to use the get class, unless yor constructor is private. If it public, use it like:

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

If you want your constructor to be private and use the getClass to get an instance of your class, you should make that method static like:

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

在c ++ / cli或托管c ++中围绕定义的类添加一个包装类。它就像一个可以直接与本机c ++和c#进行通信的层。

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM