6

我想从我的 C# 代码中调用我的非托管 C++ 库。有哪些潜在的陷阱和需要采取的预防措施?感谢您的时间。

4

8 回答 8

3

有几种方法可以使用 - 一种,您可以更新非托管 C++ 库,使其周围有一个托管 C++ 扩展包装器,并让 C# 直接利用这些类。这有点费时,但它为遗留非托管代码提供了一个很好的桥梁。但请注意,托管 C++ 扩展有时难以自行导航,因为语法类似于非托管 C++,但足够接近,训练有素的眼睛将能够看到差异。

另一条途径是让你的非管理 C++ 实现 COM 类,并让 C# 通过自动生成的互操作程序集使用它。如果您对 COM 有足够的了解,这种方式会更容易。

希望这可以帮助。

于 2008-09-16T20:33:14.830 回答
1

您正在描述 P/Invoke。这意味着您的 C++ 库需要通过 DLL 接口公开自己,并且该接口需要足够简单,以便通过调用属性向 P/Invoke 描述。当托管代码调用非托管世界时,必须对参数进行编组,因此似乎可能会对性能造成轻微影响,但您必须进行一些测试以查看编组是否重要。

于 2008-09-16T20:40:22.333 回答
1

最简单的开始方法是确保所有 C++ 功能都公开为“C”风格的函数。确保将函数声明为 _stdcall。

extern "C" __declspec(dllexport) int _stdcall Foo(int a)

确保你得到正确的编组,尤其是指针和 wchar_t * 之类的东西。如果你弄错了,可能很难调试。

从任一侧调试它,但不能同时调试它。在调试混合原生和托管时,调试器会变得非常慢。一次调试一侧可以节省大量时间。

变得更具体需要一个更具体的问题。

于 2008-09-16T20:46:21.727 回答
1

这个问题太笼统了。唯一合理的答案是 P/Invoke,但这有点像说,如果你想为 Windows 编程,你需要知道 Win32 API。

几乎整本书都是关于 P/Invoke ( http://www.amazon.com/NET-COM-Complete-Interoperability-Guide/dp/067232170X ),当然还有整个网站:http:// www.pinvoke.net/

于 2008-09-16T21:32:27.653 回答
0

您还可以通过 P/Invoke 调用非托管代码。如果您的代码当前不使用 COM,这可能会更容易。如果你走这条路,我想你可能需要使用“C”绑定在你的代码中编写一些特定的导出点。

根据我的经验,您需要注意的最重要的事情可能是缺乏确定性垃圾收集意味着您的析构函数不会像您以前认为的那样运行。您需要牢记这一点,并使用 IDisposable 或其他方法来确保您的托管代码在需要时被清理。

于 2008-09-16T20:39:28.967 回答
0

当然,如果您将代码打包为带有外部入口点的 DLL,那么总会有 PInvoke。没有一个选项是无痛的。它们取决于 a) 你在编写 COM 或托管 C 包装器方面的技能 b) 在 PInvoke 中碰巧你的手臂。

于 2008-09-16T20:44:32.900 回答
0

我会看一下swig,我们使用它来对我们的项目产生良好的效果,以将我们的 C++ API 暴露给其他语言平台。

这是一个维护良好的项目,它有效地围绕您的 C++ 库构建了一个瘦包装器,它可以允许诸如 C# 之类的语言直接与您的本机代码进行通信 - 省去了您必须实现(和调试)胶水代码的麻烦。

于 2008-09-16T21:00:21.677 回答
0

如果您想要一个好的 PInvoke 示例,您可以查看PInvoke.net。它有如何调用大多数 win api 函数的示例。

您还可以使用本文Clr Inside Out: PInvoke中的工具,它将您的 .h 文件转换为 c# 包装器。

于 2008-09-16T21:13:06.450 回答