C ++应用程序是跨平台的吗?

我作为学生学到的第一件事就是C ++应用程序不能在不同的操作系统上运行。 最近,我读到基于Qt的C ++应用程序无处不在。 那么发生了什么? C ++应用程序是否跨平台?

  1. 源代码兼容。 如果我编译源代码,它会运行在任何地方。

  2. API / ABI兼容性。 操作系统是否以代码能够理解的方式为其组件提供接口?

  3. 二进制兼容性。 代码是否可以在目标主机上运行?

源代码兼容

C++是一个定义结构,内存,文件如何被读写的标准。

 #include <iostream> int main( int argc, char ** argv ) { std::cout << "Hello World" << std::endl; } 

写入stream程数据的代码(例如grepawksed )通常是跨平台的。

当你想与用户交互时,现代操作系统有一个GUI,它们不是跨平台的,并且导致代码被写入特定的平台。

qtwxWidgets这样的wxWidgets可以实现多种平台,并且允许您为qt而不是WindowsiOS进行编程,其结果与两者兼容。

这些匿名库的问题在于,为了平台间的一致性,他们将平台X的某些特定好处带走了。

这个例子可以在Windows使用WaitForMultipleObjects函数,它允许你等待不同types的事件发生,或者在UNIX上使用fork函数,它允许你的进程的两个副本以显着的共享状态运行。 在用户界面中,表单的外观和行为略有不同(例如颜色select器,最大化,最小化,跟踪窗口外部鼠标的能力,手势行为)。

当你需要完成的工作对你来说很重要的时候,你最终可能希望编写特定于平台的代码来利用特定应用程序的优势。

Csqlite是广泛的跨平台代码,但是它的低级IO是平台特定的,所以它可以保证数据库的完整性(数据真正写到磁盘上)。

所以像Qt这样的库可以工作,它们可能会产生不令人满意的结果,并且最终不得不编写本机代码。

API / ABI兼容性

不同版本的UNIX和Windows之间有某种forms的兼容性。 这些允许为一个版本的OS构build的二进制文件在其他版本的OS上运行。

在UNIX中,您的生成机器的select定义了兼容性。 您希望支持的最低操作系统版本应该是您的构build机器,并且它将生成与后续小版本兼容的二进制文件,直到它们进行重大更改(弃用一个库)。

在Windows和Mac OS X上,您可以select一个SDK,使您可以针对一组具有相同问题的操作系统进行中断更改。

在Linux上,每个内核版本都是ABI不兼容的,内核模块需要为每个内核版本重新编译。

二进制兼容性

这是CPU了解代码的能力。 这比你想像的更为复杂,因为x64芯片可以支持运行x86代码(取决于操作系统支持)。

通常情况下,一个C ++程序打包在一个容器(PE可执行文件,ELF格式)中,操作系统使用它来解压缩代码和数据部分,并加载库。 这使得最终的程序有二进制(代码types)和API(容器的格式)不兼容的forms。

此外,如果您编译x86 Windows应用程序(针对Visual Studio 2015上的Windows 7),那么如果处理器没有SSE2指令(大约10年前的CPU),代码可能无法执行。

最后,当苹果从PowerPC改为x86时,他们提供了一个仿真层,允许旧的PowerPC代码在x86平台上的仿真器上运行。

所以一般来说二进制不兼容是一个阴暗的地方。 可以生成一个识别无效指令的操作系统(例如SSE2),并在故障中模拟行为,这可以在出现新特性时进行更新,并保持代码的运行,即使它是二进制不兼容的。

即使您的平台无法运行某种forms的指令集,也可以进行仿真并performance出兼容性。

标准C ++是跨平台的,在“一次编写,任意编译”的意义上说,而不是在“编译一次,随处运行”的意义上。

这意味着如果你用标准的C ++编写程序,你可以在任何具有标准C ++实现的目标环境下编译并运行它。

但是,您可以在您的机器上编译您的程序,运送二进制文件,然后期望它在其他目标上运行。 (至less不是一般的,当然可以在特定条件下分发C ++代码中的二进制文件,但这些依赖于实际的目标,这是一个广泛的领域)。


当然,如果您使用额外的非标准function(如gcc的可变长度数组或第三方库),则只能在提供这些扩展和库的系统上进行编译。

一些类似Qt和Boost的库在许多系统上都可用(至less我相信这两个系统在Linux,Mac和Windows上),所以如果你使用这些系统,你的代码将保持跨平台。

可以实现您的源代码在各种平台上编译 ,从相同的源代码向您提供各种二进制文件。

这不是像Java或C#那样“编译一次, 用适当的虚拟机在任何地方运行”,而是“一次写入, 用适当的环境 编译 ”,这是C一直在做的方式。

由于标准库不提供您可能需要的所有内容,因此您必须查找第三方库来提供该function。 某些框架 – 比如Boost,Qt,GTK +,wxWidgets等 – 都可以提供这个function。 由于这些框架是以在不同平台上编译的方式编写的,因此可以在前述意义上实现跨平台function。


如果你希望你的C ++代码是跨平台的,有很多东西需要注意。

显而易见的是对数据types进行假设的源代码。 你的long可能在这里32位和64位。 数据typesalignment和结构填充可能不同。 有一些方法可以在这里“安全地玩”,比如size_t / size_type / uint16_t typedefs等等,以及错误的方法,比如wchar_tstd::wstring 。 需要纪律和一些经验来“正确”。

并非所有编译器都是平等的。 如果您需要在其他C ++编译器上编译源代码,则不能使用所有最新的C ++语言function,或者使用依赖于这些function的库。 先检查兼容性图表 。

另一件事是Endianess 。 举个例子,当你在一个平台(比如x86或者x86_64)上编写一个整数stream文件,然后在不同的平台(比如说POWER)上再次读取它时,你可能遇到问题。 你为什么要写整数文件? 那么,UTF-16 整数…再次,纪律和一些经验,使这个相当无痛的很长的路要走。

一旦你检查了所有这些框,你需要确保你的代码可用性 。 尽pipestd::是安全的(但是请参阅上面的“并非所有的编译器都是相同的”),像boost::无辜的东西可能会成为一个问题,如果你超越了主stream。 (在过去的几年中,我帮助Boost人修复了一两个有关AIX / Visual Age的showstopper,仅仅是因为他们无法访问该平台来testing新版本…)

噢,注意那里的各种授权计划 。 一些改进跨平台function的框架(如Qt或Cygwin)都附有string。 这并不是说他们在正确的情况下帮助不大,只是需要了解版权/专有许可要求。


所有这一切,都有Wine (“Wine不是仿真”),它使得为Windows 编译的可执行文件可以在各种类Unix系统(Linux,OS X,* BSD,Solaris)上运行。 它的能力有一定的限制,但是它一直在变好。

是。 不,也许 什么是跨平台的C ++代码? 跨平台的C ++代码就是这样一个代码,可以在不同的操作系统下编译而不需要修改。

这意味着,如果您明确使用任何平台相关的标头,则您的代码不再是跨平台的。 Qt通过以下方式解决了这个问题:它为所有平台特定的东西提供了包装。 例如,假设您正在使用QFile打开/读取/写入文件。 你的代码看起来像

 QFile file(filename); file.open(QFile::ReadOnly); //other stuff 

你可以在任何操作系统下编译这个代码,只要你有适合该操作系统的编译器和Qt库。 隐藏在QFile下的代码将使用操作系统相应的文件处理函数,但是这不应该关注你。

另外,如果只使用标准库,则可以在任何存在C ++编译器的地方编译代码。

但是,已编译的应用程序并不是以Java应用程序的方式进行跨平台的 – 例如,您无法为Windows编译应用程序,然后在Linux中运行应用程序,则必须重新编译代码改为在Linux下。

C ++是一种编程语言。 文本。 因此,它不会在任何地方运行。

预计标准C ++代码在任何平台上的行为都是平等的; “跨平台”,如果你想。 写(严格)符合C ++代码需要pedantry,因为一些假设往往使依赖于实际实现的最终细节,这是从C + +目标inheritance的目标。

注意我们还在谈论C ++代码,而不是C ++程序。 事实上,当我们转向“程序”这个术语时,我们没有更多的保证,因为我们不再讨论C ++了。 而是编译器的输出。 这是可移植性开始消失的地方:可执行格式,ISA,ABI,低级例程等等。
你能依靠吗? 如果你不能,那么你需要通过重新编译它或使用特定于平台的元素来将你的C ++程序集成到它将运行的环境中。

C ++是跨平台的。 您可以使用它来构build可在多种不同操作系统上运行的应用程序。

什么是不跨平台的是将C ++转换成目标代码的编译器。 就我所知,没有一个单独的编译器具有所有必要的function,所以当你使用它编译C ++程序时,它将自动运行在Windows,Linux和Mac OS上。

Qt Creator与多个编译器集成,并构build自动化。 它可以很容易地在不同的设置和目标平台之间切换。 它为构build,运行和部署C ++应用程序提供支持,不仅适用于桌面环境,而且适用于移动设备。