【问题标题】:Using C++ Class DLL in C# Application在 C# 应用程序中使用 C++ 类 DLL
【发布时间】:2010-10-08 20:23:03
【问题描述】:

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

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

【问题讨论】:

  • 对不起,我应该更具体。这不是 COM 类。它只是一个普通的旧 C++ 类。

标签: c# dll c++-cli unmanaged


【解决方案1】:

假设类 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

【讨论】:

  • 如果 OP 正在处理字符串或异常,我不会调用 (5) optional。
  • 如果我想摆脱 C++ Dll 层并创建一个 C++/CLI 项目,该项目既是 DLL 又是包装器,我会怎么做?更具体地说,我当前的 C++ DLL 只是将一堆静态库链接到一个漂亮的接口中。我可以在 C++/CLI 项目中完成所有这些工作吗?
  • 是的,你可以在这个 C++/CLI 中做所有事情
  • 我把可选的,因为 api 可能没有任何字符串。将 SEH 转换为 .Net 异常对象也不是强制性的(尽管推荐)。已更改文本以明确这一点
  • 特别是 C++/CLI 项目可以包含托管和非托管类。
【解决方案2】:

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

http://www.swig.org/

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

      两种选择:

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

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

      【讨论】:

      • 能否请您为第二个选项提供一些链接/信息。谢谢
      • @rsjethani:我手头没有任何东西:创建 COM 包装器意味着编写(本机)COM。然后使用implib 为.NET 创建包装器。
      【解决方案5】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-01-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-23
        • 1970-01-01
        相关资源
        最近更新 更多