我怎样才能改变我的 C++在 C# 中用作 DLL 的代码?

发布于 2024-12-25 04:23:54 字数 770 浏览 0 评论 0原文

我正在学习如何从 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);
}

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

半世晨晓 2025-01-01 04:23:54

当您有大量静态函数时,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# 调用是相同的)。请参阅此处:托管、非托管,详细了解如何混合托管和非托管代码。

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.

白云不回头 2025-01-01 04:23:54

您不需要使用 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(); }
    };
}

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(); }
    };
}
谎言月老 2025-01-01 04:23:54

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

Add a wrapper class around your defined class in c++/cli or managed c++.It is like a layer which can cummunicate directly with both native c++ and c#

错々过的事 2025-01-01 04:23:54

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文