我正在制作一个C ++程序。
我对C ++最大的烦恼之一就是它假定的平台独立性。
你们都可能知道,在Windows中编译Linux C ++程序,在Linux中编译Linux C ++程序几乎是不可能的,而不会产生大量的神秘错误和平台特定的包含文件。
当然你可以随时切换到像Cygwin和wine这样的仿真,但我问你,有没有别的办法呢?
答案 0 :(得分:37)
语言本身是跨平台的,但大多数库都不是,但如果你想在C ++编程时想要完全跨平台,你应该记住三件事。
首先,您需要开始使用某种跨平台构建系统,例如SCons。其次,您需要确保所使用的所有库都是跨平台构建的。 第三点,我建议使用存在于所有目标平台上的编译器,gcc在这里考虑(C ++是一个相当复杂的野兽,所有编译器都有自己特定的怪癖)。
我有一些关于图形用户界面的进一步建议。有几个可供使用,最值得注意的三个是:
GTK+和QT是两个API,它们带有自己的小部件集(按钮,列表等),而wxWidgets更像是当前运行平台的包装API本机小部件集。这意味着两个前者与系统的其他部分相比可能看起来有点不同,而后者看起来就像本机程序。
如果你正在进行游戏编程,那么有很多API可供选择,所有这些都是跨平台的。我所知道的最全面的两个是:
两者都包含从图形到输入和音频例程的所有内容,无论是通过插件还是内置。
另外,如果您觉得C ++中的标准库有点缺乏,请查看Boost以获得一些通用的跨平台甜蜜。
祝你好运。
答案 1 :(得分:13)
C ++是跨平台的。您似乎遇到的问题是您正在使用平台相关库。
我假设你真的在谈论UI组件 - 在这种情况下我建议使用像GTK +,Qt或wxWindows这样的东西 - 每个都有可以为不同系统编译的UI组件。
唯一的解决方案是让您找到并使用独立于平台的库。
并且,在旁注中,cygwin或Wine都不是仿真 - 它们是100%本机实现的相同功能的发现它们各自的系统。
答案 2 :(得分:9)
一旦你意识到了问题,它实际上并不那么难。我目前正在处理的所有代码都编译在32位和64位Windows上,所有类型的 Linux ,以及Unix(Sun,HP和IBM)。显然,这些不是GUI产品。此外,我们不使用第三方库,除非我们自己编译它们。
我有一个.h文件,其中包含所有特定于编译器的代码。例如,Microsoft和gcc在如何指定8位整数方面存在分歧。所以在.h中,我有
#if defined(_MSC_VER)
typedef __int8 int8_t;
#elif defined(__unix)
typedef char int8_t;
#endif
还有相当多的代码可以统一某些低级函数调用,例如:
#if defined(_MSC_VER)
#define SplitPath(Path__,Drive__,Name__,Ext__) _splitpath(Path__,Drive__,Dir__,Name__,Ext__)
#elif defined(__unix)
#define SplitPath(Path__,Drive__,Name__,Ext__) UnixSplitPath(Path__,Drive__,Name__,Ext__)
#endif
现在在这种情况下,我相信我必须编写一个UnixSplitPath()函数 - 有时您需要。但大多数时候,你只需要找到正确的替换功能。在我的代码中,我将调用SplitPath(),即使它不是任何平台上的本机函数; #defines将为我排序。培训自己需要一段时间。
信不信由你,我的.h文件只有240行。这真的不多。这包括处理endian问题。
一些较低级别的东西需要条件编译。例如,在Windows中,我使用Critical Sections,但在Linux中我需要使用pthread_mutex。 CriticalSection被封装在一个类中,这个类有很多条件编译。但是,上层程序完全没有意识到,无论平台如何,类的功能都完全相同。
我能给你的另一个秘诀是:经常在所有平台上构建你的项目(特别是在开始时)。当您将编译器问题扼杀在萌芽状态时,这会容易得多。在你尝试跨平台之前,不要等到你完成开发。
答案 3 :(得分:2)
坚持使用ANSI C ++和跨平台的库,你应该没问题。
答案 4 :(得分:1)
创建一个低级图层,其中包含项目中所有特定于平台的代码。实现此层的2个版本 - 一个用于Windows,一个用于Linux - 具有相同的接口,并将它们构建到2个库。通过该界面访问项目中所有特定于平台的功能。
此图层可以包含文件访问,打印,GUI等的常规类。
使用该层的所有(现在非特定于平台的)代码现在可以在Windows上编译一次,在Linux上编译一次。
答案 5 :(得分:0)
在Window中再编译,在Linux中再次编译。除非您使用特定于平台的库,否则它应该可行。它不像Java,你可以编译一次,它可以在任何地方使用。没有人为C ++制作虚拟机,也许永远不会。用C ++编写的代码可以在任何平台上运行。你只需要先在每个平台上编译它。
答案 6 :(得分:0)
建议:
使用typedef进行整数。或#include< stdint.h>。有些机器认为int是8个字节,有些是4个。(以前是2和4个。时间如何变化。)
尽可能使用封装。我的最后一个窗口的编译器认为%lld是%I64d“,为vsnprintf()提供了棘手的返回值,与close()和套接字等类似的问题。
注意堆栈大小/缓冲区大小限制。我在Windows下遇到了8k UDP缓冲区限制,以及其他问题。
出于某种原因,我的Window的C ++编译器不接受堆栈的动态大小分配。例如:void foo(int a){int b [a];要注意那些事情。计划如何重新编码。
#ifdef可以成为你最好的朋友。而你最大的敌人! (同时!)
当然可以做到。但是要经常进行编译和测试!
答案 7 :(得分:0)
Linux和Windows也有不同的数据模型。 请参阅文章:The forgotten problems of 64-bit programs development
答案 8 :(得分:-1)
标准C ++ 是代码在任何平台上编译都没有错误。 尝试在Windows上使用 Bloodshed Dev C ++ (而不是VC ++ / Borland C ++)。
由于Bloodshed Dev C ++确认了C ++标准,因此在大多数情况下,使用它编译的程序将在linux上编译而没有错误。