我对在 c# 中包装 c++ dll 感到有点困惑。我应该创建什么样的dll?一个普通的dll还是一个mfc dll?我应该在每个原型前加上“extern ...”吗?我应该在def文件中编写函数吗?
我最后的努力是徒劳的,c#会因为“错误的图像格式”之类的错误而崩溃,这意味着dll格式不正确?
任何帮助将非常感激。
提前致谢 :-)
您使用的是 64 位 PC 吗?
如果您尝试混合使用 x64 代码和 x86 代码,则会在 x64 系统上出现“错误的图像格式”。如果您编写调用非托管 DLL(默认情况下可能是 x86)的 C# 代码(针对“任何 CPU”,因此它将 jit 编译为 x64 代码),就会发生这种情况。
对此的两种解决方案是:
否则,您应该能够创建一个普通的 COM dll(不管有没有 MFC),然后将其包装在 RCW(运行时可调用包装器)中。
您可以创建一种普通的 C++ dll,并从您的 C# 代码中与它进行互操作。
这是您可以使用的教程。
您可以尝试使用 C++/CLI 创建一个 .NET dll。.NET-Dll 在 C# 中易于使用,并且可以自然地访问 c++-dll。这就是 MOGRE 为 OGRE 创建包装器的方式。
我不确定,但SWIG可能会帮助您完成这项任务。我没有使用过它,但它被大量用于创建包装器。
除非你真的需要它是一个 COM/MFC dll,例如你需要将它插入到一个 MFC 应用程序中,那么如果你把它变成一个直接的 C++ .dll,事情可能会更清楚。
回答您关于 extern 关键字的问题 - 我认为这仅在调用应用程序中使用,当您包含 .lib 文件时。
这是创建直接 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 做了类似的事情,我认为这并不像听起来那么糟糕。
这是有关如何执行此操作的教程。