繁体   English   中英

是否可以通过托管C ++ / CLI项目正常运行非托管C ++?

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

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

  1. 非托管lib是一个非常复杂的C ++库,它使用了很多内联和其他功能,因此我无法将其编译到/clr -marked托管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功能?

您可以从普通的本机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 ++异常, 使用SEH异常(/ EHa)将其更改为
  • /RTC - 运行时检查,将其更改为默认值
  • 预编译头 - 将其更改为“ 不使用预编译头”
  • /GR- - 运行时类型信息 - 将其更改为开(/ 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开始,还有一些可用的Intellisense。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM