在C#应用程序中使用C++类DLL

46

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

该如何正确地在我的C#应用程序中使用这个类?


1
抱歉,我应该更具体地说明。这不是一个COM类,而只是一个普通的C++类。 - cjserio
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。


如果OP正在处理字符串或异常,我不会将(5)称为可选项。 - Timo Geusch
如果我想要摆脱 C++ DLL 层,只创建一个既是 DLL 又是包装器的 C++/CLI 项目,我该怎么做?更具体地说,我的当前 C++ DLL 只是将一堆静态库链接成一个漂亮的接口。我能在 C++/CLI 项目中完成所有这些工作吗? - cjserio
是的,你可以在C++/CLI中做所有的事情。 - ShuggyCoUk
我使用了“可选”一词,因为API可能没有任何字符串。将SEH转换为.Net异常对象也不是强制性的(尽管建议这样做)。我已经修改了文本以明确这一点。 - ShuggyCoUk
具体来说,C++/CLI项目可以包含托管和非托管类。 - ShuggyCoUk

8
这个答案可能有些过于详细了,但是SWIG是一个很好的解决方案,可以将C/C++类“包装”以供其他语言使用。它与C#兼容性良好。
请参见http://www.swig.org/

3

DllImport是您最好的选择。如果您要传递结构体,可能需要进行一些数据类型转换,但您几乎可以使用它来完成任何操作。


2
你需要一个代理(GoF模式)中介来连接托管/非托管边界。
两个选项:
1. C++/CLI包装器 2. COM包装器
前者更直接,后者有两个步骤:纯C++->COM->.NET。

你能否提供第二个选项的一些链接/信息。谢谢 - rsjethani
@rsjethani:我手头没有任何东西:创建COM包装器意味着编写(本地)COM。然后使用implib为.NET创建包装器。 - Richard

2

有时候,提供自己的C接口会更加容易。 SWIG 的设置非常复杂。我曾经使用过managed C++和C++/CLI,它们都很好用。最简单的方法是编写一个C包装器(几乎可以被任何其他语言调用,因为大多数语言都有调用C函数的方式)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接