2009-02-20 66 views
42

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

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

+1

它是一个COM类吗? – 2009-02-20 13:46:40

+1

对不起,我应该更具体。这不是一个COM类。这只是一个普通的旧C++类。 – cjserio 2009-02-20 13:47:11

回答

43

简单的方法假设类Foo:

  1. 创建一个C++/CLI项目,调用此FooWrapper。
  2. Make FooWrapper依赖于非托管dll(不过您通常会这样做)。
  3. 创建托管类ManagedFoo,其中包含类型为Foo *的单个私有实例字段。
  4. 在ManagedFoo中提供公共包装函数,该函数将转发到基础实例字段。
  5. 任选的(虽然推荐):从.NET成语(字符串等)到C++成语(的std :: string或字符*)
  6. 捕捉非托管异常
    • 转换参数,并抛出管理的人,而不是

然后你让你的C#代码依赖于FooWrapper项目/ DLL,并确保非托管LL正确地部署它,如何做到这一点取决于非托管的DLL,但在同一个目录通常是足够的。

如果功能不依赖于类的实例,然后更简单的的P/Invoke

+0

虽然,如果OP处理字符串或异常,我不会调用(5)可选。 – 2009-02-20 13:55:24

2

你需要一个代理(GoF模式)中介弥合托管/非托管边界。

两个选项:

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

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

8

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

请参阅http://www.swig.org/

3

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

2

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