是否有可能从托管c++ /CLI项目中正常运行非托管c++ ?

Is it possible to run unmanaged C++ normally from a managed C++/CLI project?

本文关键字:c++ 正常运行 项目 有可能 是否 CLI      更新时间:2023-10-16

我正在c++/CLI中包装一个纯非托管vc++ 9项目,以便从。net应用程序中使用它。我知道如何编写包装器,并且非托管代码可以从。net执行,但我不能完全包装我的头:

  1. 非托管库是一个非常复杂的c++库,使用了很多内联和其他功能,所以我不能将其编译成/clr标记的托管DLL。我需要使用正常的vc++编译器将其编译成一个单独的DLL。

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

  3. 如何从c++/CLI项目中访问导出的符号?我是否只是包含非托管源代码的头文件,而c++链接器将从非托管DLL中获取实际代码?或者我必须在指向DLL中的类的新头文件中手工编写一组单独的"外部"类吗?

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

  5. c++项目创建了许多实例,并有自己的自定义实现的垃圾收集器,所有这些都是用普通c++编写的,它是一个DirectX声音渲染器,并管理许多DirectX对象。所有这些工作是否正常,或者这些Win32功能是否会受到任何影响?

你可以从一个普通的本地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.cpp CLR代码中自由实现或调用它。编译器/链接器组合处理一切。在CLR代码中不需要做任何特殊的操作来调用本机代码。

你可能会得到关于不兼容开关的编译错误:

  • /ZI - 程序数据库用于编辑和继续,将其更改为仅程序数据库
  • /Gm -你需要禁用最小重建
  • /EHsc - c++异常,将其更改为Yes with SEH exceptions (/EHa)
  • /RTC -运行时检查,更改为默认
  • 预编译头-将其更改为不使用预编译头
  • /GR- - Runtime Type Information -将其更改为On (/GR)

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

正如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开始,也有一些可用的智能感知。

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

似乎也有c++互操作技术可以使用:http://msdn.microsoft.com/en-us/library/2x8kf7zx(v=vs.80).aspx