5

我正在用 C++/CLI 包装一个纯非托管 VC++ 9 项目,以便从 .NET 应用程序中简单地使用它。我知道如何编写wrappers,并且可以从 .NET 执行非托管代码,但我无法完全理解:

  1. 非托管库是一个非常复杂的 C++ 库,并且使用了很多内联和其他功能,因此我无法将其编译到 -/clr标记的托管 DLL 中。我需要使用普通的 VC++ 编译器将它编译成一个单独的 DLL。

  2. 如何从此非托管代码中导出符号,以便在 C++/CLI 项目中使用它?我是否将我需要的每个课程都标记为可见extern?是这么简单还是有一些更复杂的?

  3. 如何从 C++/CLI 项目访问导出的符号?我是否只包含非托管源代码的头文件, C++ 链接器是否会从非托管 DLL 中获取实际代码?还是我必须在指向 DLL 中的类的新头文件中手动编写一组单独的“extern”类?

  4. 当我的 C++/CLI 项目创建非托管类时,非托管代码会在正常的 VC9 运行时中完美运行,还是会被迫在 .NET 中运行?导致更多兼容性问题?

  5. C++ 项目创建了许多实例,并有自己的自定义实现的垃圾收集器,全部用纯 C++ 编写,它是一个 DirectX 声音渲染器并管理许多 DirectX 对象。这一切会正常工作还是会以任何方式影响此类 Win32 功能?

4

3 回答 3

8

您可以从一个普通的本机 C++ 项目开始(例如,从十多年前的 Visual Studio 6.0 导入),当您今天构建它时,它将链接到当前版本的 VC 运行时。

然后,您可以向其中添加一个新foo.cpp文件,但要配置该文件,使其启用 /CLR 标志。这将导致编译器从该文件生成 IL,并链接一些额外的支持,导致 .NET 框架在启动时加载到进程中,因此它可以 JIT 编译然后执行 IL。

应用程序的其余部分仍然像以前一样在本地编译,完全不受影响。

事实是,即使是“纯”CLR 应用程序也确实是混合的,因为 CLR 本身(显然)是本机代码。混合 C++/CLI 应用程序通过允许您添加更多与某些 CLR 托管代码共享进程的本机代码来扩展这一点。它们在过程的整个生命周期内共存。

如果您foo.h使用声明制作标题:

void bar(int a, int b);

您可以在本机代码或foo.cppCLR 代码中自由实现或调用它。编译器/链接器组合负责一切。不需要做任何特殊的事情来从 CLR 代码中调用本机代码。

您可能会收到有关不兼容开关的编译错误:

  • /ZI-用于编辑和继续的程序数据库,将其更改为仅程序数据库
  • /Gm- 你需要禁用最小重建
  • /EHsc- C++ 异常,使用 SEH Exceptions (/EHa) 将其更改为 Yes
  • /RTC- 运行时检查,将其更改为默认值
  • 预编译头文件 - 将其更改为不使用预编译头文件
  • /GR-- 运行时类型信息 - 将其更改为On (/GR)

所有这些更改只需要在您启用 /CLR 的特定文件上进行。

于 2013-03-24T12:49:10.747 回答
1

正如 Daniel 所说,您可以在文件级别微调您的设置。您也可以在文件中使用“#pragma managed”,但我不会无缘无故地这样做。

请记住,您可以创建一个完整的混合模式程序集。这意味着,您可以将您的本机代码原封不动地编译到该文件中,外加一些围绕该代码的 C++/CLI 包装器。最后,您将拥有与本机 Dll 相同的文件,其中包含所有导出的本机符号和成熟的 .NET 程序集(公开 C++/CLI 对象)!

这也意味着,只要考虑文件外的本机客户端代码,您只需关心导出。混合 dll/程序集内的 C++/CLI 代码可以使用通常的访问规则访问本机数据结构(只需包含标头即可)

因为您提到了它,所以我为一些重要的本机 C++ 类层次结构执行了此操作,包括相当数量的 DirectX 代码。所以,这里没有主要问题。

我建议不要在 .NET 驱动的环境中使用 pInvoke。没错,它有效。但是对于任何重要的事情(比如超过 10 个函数),使用 C++/CLI 提供的 OO 方法肯定会更好。您的 C# 客户端开发人员将不胜感激。在 C++/CLI 中,您拥有所有 .NET 的东西,例如委托/属性、托管线程等等。从 VS 2012 开始,也有一些可用的 Intellisense。

于 2013-03-24T19:41:50.033 回答
0

您可以使用 PInvoke 从非托管 DLL 调用导出的函数。这就是从 .Net 访问非托管 Windows API 的方式。但是,如果您的导出函数使用 C++ 对象,而不仅仅是普通的 C 数据结构,您可能会遇到问题。

似乎还有对您有用的 C++ 互操作技术:http: //msdn.microsoft.com/en-us/library/2x8kf7zx (v=vs.80).aspx

于 2013-03-24T12:31:39.440 回答