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

时间:2015-10-20 13:43:14

标签: c++ cross-platform

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

6 个答案:

答案 0 :(得分:60)

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

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

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

  4. 兼容源代码

    C++是一个标准,它定义了如何读取和写入结构,内存,文件。

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

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

    当您想要与用户交互时,现代操作系统有一个GUI,这些不是跨平台的,并且会导致为特定平台编写代码。

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

    这些匿名库的问题是,为了跨平台的统一性,它们将平台X的一些特定优势带走。

    这样的示例将在Windows上使用WaitForMultipleObjects函数,它允许您等待发生不同类型的事件,或者在UNIX上使用fork函数,这允许两个正在以重要共享状态运行的进程副本。在UI中,表单的外观和行为略有不同(例如,颜色选择器,最大化,最小化,在窗口外跟踪鼠标的能力,手势的行为)。

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

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

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

    API / ABI兼容性

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

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

    在Windows和Mac OS X上,您选择了一个SDK,它允许您针对一组操作系统定位,这些操作系统具有相同的重大更改问题。

    在Linux上,每个内核修订版都与其他任何内核修订版不兼容,并且需要为每个内核修订版重新编译内核模块。

    二进制兼容性

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

    通常,C ++程序打包在容器(PE可执行文件,ELF格式)中,操作系统使用该容器来解压缩代码和数据部分以及加载库。这使得最终程序具有二进制(代码类型)和API(容器格式)形式的不兼容性。

    今天如果你编译一个x86 Windows应用程序(在Visual Studio 2015上面向Windows 7),那么如果处理器没有SSE2指令(大约10年的CPU),代码可能无法执行。

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

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

    即使您的平台无法运行某种形式的指令集,也可以模拟它并兼容行为。

答案 1 :(得分:58)

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

这意味着如果您使用标准C ++编写程序,则可以编译然后在具有标准符合C ++实现的任何目标环境中运行它。

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

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

Qt和Boost等一些库在许多系统上都可用(至少我认为这两个在Linux,Mac和Windows上都有),所以如果你使用它们,你的代码将保持跨平台。

答案 2 :(得分:18)

可以在各种平台上实现您的源编译,为您提供来自同一源代码库的各种二进制文件。

这不是&#34;编译一次,在任何地方使用适当的VM运行&#34;正如Java或C#那样做,但是&#34;在适当的环境的任何地方用编译 &#34; C一直在做的方式。

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

如果您希望C ++代码是跨平台的,那么有很多事情需要注意。

显而易见的是,对数据类型进行假设的来源。你的long可能是32位,而那里是64位。数据类型对齐和结构填充可能不同。有很多方法可以安全地发挥它的作用。这里,如size_t / size_type / uint16_t typedef等,以及错误的方法,例如wchar_tstd::wstring。需要纪律和一些经验才能做到正确&#34;。

并非所有编译器都是相同的。如果您需要在其他C ++编译器上编译源代码,则不能使用所有最新的C ++语言功能,或使用依赖这些功能的库。首先检查compatibility chart

另一件事是endianess。举一个例子,当您在一个平台(例如,x86或x86_64)上编写整数流文件,然后在另一个平台(例如POWER)上再次读取它时,您可能会遇到问题。为什么要写整数来归档?好吧,UTF-16 整数...再次,纪律和一些经验对于使这个相当无痛而言还有很长的路要走。

一旦您检查了所有那些框,您需要确保基于代码的库的可用性。虽然std::是安全的(但请参阅&#34;并非所有编译器都是相同的&#34;以上),如果您超越主流,那么像boost::这样无辜的东西可能会成为一个问题。 (过去几年,我帮助Boost人修复了关于AIX / Visual Age的一两个showstoppers,因为他们无法访问该平台来测试新版本......)

哦,请注意那里的各种许可方案。一些改进跨平台功能的框架(如Qt或Cygwin)附加了字符串。这并不是说它们在适当的情况下不是一个很大的帮助,只需要了解copyleft /专有许可要求。

所有这一切,都有Wine(&#34; Wine不是仿真&#34;),它为Windows 运行生成可执行文件已编译在各种类似Unix的系统上(Linux,OS X,* BSD,Solaris)。它的功能有一定的限制,但它一直在变好。

答案 3 :(得分:6)

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

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

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

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

此外,如果您只使用标准库,则可以在存在C ++编译器的任何位置编译代码。

然而,已编译的应用程序并不是跨平台的,例如,Java应用程序是 - 例如,您无法为Windows编译应用程序然后在Linux中运行,您将不得不在Linux下重新编译你的代码。

答案 4 :(得分:4)

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

在任何平台上,符合标准C ++代码都应该行为;如果你愿意,可以“跨平台”。编写(严格地)符合C ++代码需要迂腐,因为一些假设经常依赖于对实际实现而言最终的细节,并且这是从C ++本身的目标继承而来的。

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

答案 5 :(得分:3)

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

什么不是跨平台的是将C ++转换为目标代码的编译器。据我所知,没有一个编译器具有所有必要的功能,因此当您使用它编译C ++程序时,它将自动在Windows,Linux和Mac OS上运行。

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