【发布时间】:2011-01-18 11:53:05
【问题描述】:
我有一个本地 C++ dll、一些头文件和导入库。有没有办法在 C# 中实例化 dll 中定义的对象?
我知道的两种方式是:
- 将 C++ 代码包装到 COM 中
- 使用 DLLImport 和外部 C 函数
【问题讨论】:
-
您的 C++ 代码是否依赖于任何其他库,例如 boost?
-
是的。 FLOPC++(但它不是我的 C++ 代码)。
我有一个本地 C++ dll、一些头文件和导入库。有没有办法在 C# 中实例化 dll 中定义的对象?
我知道的两种方式是:
【问题讨论】:
C++/CLI 是你的朋友。不过,您会遇到一个问题:无法将标准 C++ 对象存储在 C++/CLI 引用或值类(.NET 的类)中。所以你必须求助于我在生产代码中使用的以下类(你可以修改):
#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(); }
};
用法:Handle<MyCppClass>^ handle; 在 C++/CLI 类中。然后实现存根方法,将它们转发给handle 成员。如果没有更多指向它的指针,垃圾收集对象将调用 C++ 类实例的析构函数:
public ref class Foo
{
void bar() { handle->bar(); }
internal:
Handle<CppNamespace::Foo>^ handle;
};
【讨论】:
cli::gcroot 类模板。您可能还想在 cli::pin_ptr 类模板上记录。
我认为您的选择只是构建一个 C++/CLI 类包装器(因此您可以像引用 c# 类一样引用它),否则您无法从 c# 代码实例化 c++ 类(非托管)。
替代方法可能是“丑陋”的方式:通过 c 函数实例化 c++ 类,但您会将该类视为 c# 代码中的 void 指针,因此您基本上不会对它做任何事情(除非您创建与此类交互的其他函数;仅限 C 函数)
C# 理解 C,如果你想让它理解 C++,你必须使用 C++/CLI
附: C# 对 C++ 类有一些基本的了解,但它只是将类数据(我的意思是字节:字段)转换为 C# 中的一些可用数据(有一些属性),但不允许使用方法和类似的东西(避免完全是我的建议)。
【讨论】: