如何更改我的C ++代码以在C#中用作DLL?

时间:2012-01-05 12:29:50

标签: c# c++ pinvoke

我正在学习如何用C#调用C ++中的方法。我做了一些研究,看起来Pinvoke是一个不错的方式。

如何将这个简单的C ++代码转换为在C#中调用它的方式,以及如何编写要在C#中调用的方法?

我有一个头文件:

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;
   }
}

在C#中,

我想:

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

我不知道应该如何实现,所以我认为最好问一下。

4 个答案:

答案 0 :(得分:7)

当你有很多静态函数时,P / Invoke更适合。您可以使用C++/CLI,这在您拥有一组C ++类或类的结构化域模型层次结构时更合适。这就是你如何使用你的样本:

.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);
    }
}

如您所见,您不需要像C ++ / CLI那样使用getClass函数,您的MathFuncs类将成为一个完整的.NET类。

编辑:如果你想在非托管代码中进行实际计算(样本中的a + b),你可以这样做;例如:

.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)
}

在这种情况下,MyMathFuncsImpl :: Add是作为本机代码生成的,而不是IL(从C#调用是相同的)。有关如何混合托管代码和非托管代码的详细信息,请参阅此处:managed, unmanaged

答案 1 :(得分:0)

除非yor构造函数是私有的,否则您不需要使用get类。 如果是公开的,请使用它:

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

如果您希望构造函数是私有的并使用getClass来获取类的实例,则应该将该方法设置为静态:

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

答案 2 :(得分:0)

在c ++ / cli或托管c ++中围绕你定义的类添加一个包装类。它就像一个可以直接与native c ++和c#

组合的层。

答案 3 :(得分:0)

使用Microsoft Visual Studio(Express),我按照正常情况创建了类(当然没有main()函数),但您可以选择编译为.dll。优点是,该类将位于一个单独的文件中,该文件可以从您正在开发的其他应用程序中重用/调用。