编写C ++ DLL,然后将其包装在C#中

时间:2009-11-25 06:26:43

标签: c# c++ dll wrapper binding

我对在c#中包装c ++ dll感到有点困惑。 我应该创建什么样的DLL?一个正常的dll还是一个mfc dll?我应该用“extern ......”为每个原型加上前缀吗?我应该在def文件中编写函数吗?

我的最后努力是徒劳的,c#会因“坏图像格式”之类的错误而崩溃,这意味着dll格式不正确?

非常感谢任何帮助。

提前致谢: - )

4 个答案:

答案 0 :(得分:4)

您使用的是64位PC吗?

如果您尝试混合x64代码和x86代码,x64系统上将出现“错误的图像格式”。如果您编写C#代码(针对“任何CPU”,因此它将jit-compile到x64代码)调用非托管DLL(默认情况下可能是x86),就会发生这种情况。

两个解决方案是:

  • (正确的解决方案)确保将dll编译为目标x64,以便整个程序可以作为本机64位应用程序运行,或者
  • (向后兼容性解决方案)强制整个应用程序作为x86应用程序运行。在C#项目属性中,将Build“Any CPU”设置更改为“x86”。

否则,您应该能够创建一个普通的COM DLL(有或没有MFC应该无关紧要),然后将其包装在RCW(运行时可调用包装器)中。

答案 1 :(得分:2)

您可以创建一个普通的C ++ dll,并使用C#代码与它互操作。

您可以使用a tutorial

答案 2 :(得分:1)

您可以尝试使用C ++ / CLI创建.NET dll。 .NET-Dll在C#中很容易使用,并且可以自然地访问c ++ - dll。这就是MOGRE为OGRE创建包装器的方式。

我不确定,但SWIG可能会帮助您完成此任务。我没有使用它,但它被用于创建包装器。

答案 3 :(得分:0)

除非你真的需要它作为一个COM / MFC DLL,例如你需要将它插入一个MFC应用程序,如果你把它变成一个直接的C ++ .dll,那么你可能会更清楚。

在回答有关extern关键字的问题时 - 我认为只有在包含.lib文件时才会在调用应用程序中使用。

Here是一个关于创建直接C ++ dll的教程。

一旦你拥有了你的dll,那么问题就变成了你在你的dll中处理非托管代码而不是你的C#应用​​程序中的托管代码。换句话说,因为C ++对C#中使用的托管类型一无所知,同样,C#也不知道如何处理C ++ dll中使用的类型的内存,然后由你来管理你的dll中的内存。 C#垃圾收集器只能处理C#应用程序中的内存。

我认为答案可能是在C ++中创建一个'普通'dll,然后在包含所有内存管理的C ++ / CLI中为它创建一个包装器 - 以及从C ++非托管类型到C#类型的转换,反之亦然。您可能需要使用marshal类在托管类型(C#)和非托管类型(C ++)之间进行转换。然后,直接导入C ++ / CLI 包装器而不是C ++ dll。然后调用函数在C#应用程序中变得微不足道,因为包装器完成了“桥接工作”。

我已经使用第三方C ++ dll做了类似的事情,我认为这听起来并不像它那么糟糕。

Here是关于如何执行此操作的教程。