46

我有一个非托管 C++ DLL,它只导出一个类(不是 COM ......它只是一个简单的 C++ 类)作为它的接口。我想在 C# 中使用这个类,但被告知它不能仅仅导入到 C# 中。

在我的 C# 应用程序中使用此类的正确方法是什么?

4

5 回答 5

44

假设类 Foo 的简单方法:

  1. 创建一个 C++/CLI 项目,调用这个 FooWrapper。
  2. 使 FooWrapper 依赖于非托管的 dll(但是你通常会这样做)。
  3. 创建一个托管类 ManagedFoo,其中包含一个 Foo* 类型的私有实例字段。
  4. 在 ManagedFoo 中提供公共包装函数,这些函数转发到底层实例字段。
  5. 可选(尽管推荐):
    • 将参数从 .net 惯用语(字符串等)转换为 C++ 惯用语(std::string 或 char*)
    • 捕获非托管异常并抛出托管异常

然后你让你的 c# 代码依赖于 FooWrapper 项目/dll 并确保非托管 dll 与它一起正确部署,如何完成取决于非托管 dll 但在同一目录中通常就足够了。

如果函数不依赖于类的实例,那么更简单的是 P/Invoke

于 2009-02-20T13:53:43.033 回答
8

对于单个类库来说,这个答案可能有点矫枉过正,但 SWIG 是一个很好的解决方案,可以“包装”C/C++ 类以供其他语言使用。它适用于 C#。

http://www.swig.org/

于 2009-02-20T14:24:35.877 回答
3

DllImport 是您最好的选择。有一些数据类型按摩,特别是如果你传递结构,但你几乎可以用它做任何事情。

于 2009-02-20T15:18:24.780 回答
2

您需要一个代理(GoF 模式)中介来桥接托管/非托管边界。

两种选择:

  • C++/CLI 包装器
  • COM 包装器。

前者会更直接,后者有两个步骤pure C++ -> COM -> .NET。

于 2009-02-20T13:55:12.450 回答
2

有时,提供自己的 C 接口会更容易。 SWIG的设置并非易事。我使用了托管 C++ 和 C++/CLI,它们都很好。最简单的就是做一个 C 包装器(并且可以被任何其他语言使用,因为大多数语言都有调用 C 函数的方法)。

于 2009-02-20T21:01:22.800 回答