如何导入和使用非托管 C++来自 C# 的类?

发布于 2024-10-12 06:58:20 字数 148 浏览 6 评论 0原文

我有一个本机 C++ dll、一些头文件和导入库。有没有办法在 C# 中实例化 dll 中定义的对象?

我知道的两种方法是:

  1. 将 C++ 代码包装到 COM 中
  2. 以使用 DLLImport 和外部 C 函数

I have an native C++ dll, some header files and the import library. Is there a way how to instantiate an object within C# that is defined in the dll?

The two ways I'm aware of are:

  1. to wrap the C++ code into COM
  2. to use DLLImport and external C functions

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

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

发布评论

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

评论(2

放我走吧 2024-10-19 06:58:20

C++/CLI 是你的朋友。不过,您会遇到一个问题:无法在 C++/CLI 引用或值类(.NET 的类)中存储标准 C++ 对象。因此,您必须求助于我在生产代码中使用的以下类(您可以修改):

#pragma once
#include <boost/shared_ptr.hpp>

template <typename T>
ref class Handle
{
    boost::shared_ptr<T>* t;

    !Handle() 
    {
        if (t != nullptr)
        {
            delete t;
            t = nullptr;
        }
    }

    ~Handle() { this->!Handle(); }

public:
    Handle() : t(new boost::shared_ptr<T>((T*)0)) {}

    Handle% operator=(T* p)
    {
        if (p != t->get()) t->reset(p);
        return *this;
    }

    static T* operator&(Handle% h) { return h.t->get(); }
    static boost::shared_ptr<T> operator->(Handle% h) { return *h.t; }

    T& reference() { return *t->get(); }
    T const& const_reference() { return *t->get(); }
};

用法:C++/CLI 类中的 Handle^ handle;。然后,您实现存根方法,将它们转发给 handle 成员。垃圾收集的对象将调用 C++ 类实例的析构函数,前提是不再有指向它的指针:

public ref class Foo
{
    void bar() { handle->bar(); }

internal:
    Handle<CppNamespace::Foo>^ handle;
};

C++/CLI is your friend for this. You'll run into one problem though: it is not possible to store standard C++ objects inside C++/CLI ref or value classes (the ones for .NET). So you'll have to resort to the following class (that you can modify) that I use in production code:

#pragma once
#include <boost/shared_ptr.hpp>

template <typename T>
ref class Handle
{
    boost::shared_ptr<T>* t;

    !Handle() 
    {
        if (t != nullptr)
        {
            delete t;
            t = nullptr;
        }
    }

    ~Handle() { this->!Handle(); }

public:
    Handle() : t(new boost::shared_ptr<T>((T*)0)) {}

    Handle% operator=(T* p)
    {
        if (p != t->get()) t->reset(p);
        return *this;
    }

    static T* operator&(Handle% h) { return h.t->get(); }
    static boost::shared_ptr<T> operator->(Handle% h) { return *h.t; }

    T& reference() { return *t->get(); }
    T const& const_reference() { return *t->get(); }
};

Usage: Handle<MyCppClass>^ handle; inside a C++/CLI class. You then implement stub methods, forwarding them to the handle member. Garbage collected objects will call destructors of the C++ class instance iff there is no more pointer to it:

public ref class Foo
{
    void bar() { handle->bar(); }

internal:
    Handle<CppNamespace::Foo>^ handle;
};
旧时光的容颜 2024-10-19 06:58:20

我认为你的选择只是构建一个 C++/CLI 类包装器(这样你就可以像 ac# 类一样引用它),否则你无法从 c# 代码实例化 c++ 类(非托管)。

另一种方法可能是“丑陋”的方式:通过 ac 函数实例化 c++ 类,但您会将该类视为 c# 代码中的 void 指针,因此您基本上不会对其执行任何操作(除非您创建其他函数来与此类交互;仅 C 函数)

C# 理解 C,如果你想让它理解 C++,你必须使用 C++/

CLI
C# 对 C++ 类有一些基本的了解,但它只是将类数据(我的意思是字节:字段)转换为 C# 中的一些可用数据(有一些属性),但不允许使用方法和类似的东西(避免完全是我的建议)。

I think that your option is only build a C++/CLI class wrapper (so you can reference it like a c# class), otherwise you can't instantiate a c++ class (unmanaged) from c# code.

Alternative could be the "ugly" way: instantiate the c++ class through a c function, but you'll treat the class as a void pointer inside the c# code, so you basically will not do anything with it (except if you create other functions to interact with this class; only C functions)

C# understands C, if you want make it understand C++ you have to use C++/CLI

P.S.
C# has some basic understanding of C++ classes, but it's only about converting class data (I mean bytes: fields) into some usable data in C# (there are some Attributes), but will not allow to work with methods and things like that (avoid totally is my suggestion).

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