我正在制作一个 C++ 程序。
我对 C++ 最大的烦恼之一是它所谓的平台独立性。
大家可能都知道,在没有大量神秘错误和特定于平台的包含文件的情况下,在 Windows 中编译 Linux C++ 程序和在 Linux 中编译 Windows 程序几乎是不可能的。
当然你总是可以切换到像 Cygwin 和 wine 这样的仿真,但我问你,真的没有别的办法吗?
该语言本身是跨平台的,但大多数库不是,但是如果您想在使用 C++ 编程时完全跨平台,则应牢记三件事。
首先,您需要开始使用某种跨平台构建系统,例如SCons。其次,您需要确保您使用的所有库都是跨平台的。第三点,我建议使用所有目标平台上都存在的编译器,这里要考虑gcc(C++ 是一个相当复杂的野兽,所有编译器都有自己的特定怪癖)。
我有一些关于图形用户界面的进一步建议给你。其中有几种可供使用,最值得注意的三个是:
GTK+和QT是两个 API,它们带有自己的小部件集(按钮、列表等),而wxWidgets更像是当前运行平台本机小部件集的包装 API。这意味着与系统的其他部分相比,前者看起来可能有点不同,而后者看起来就像一个原生程序。
如果你喜欢游戏编程,那么有同样多的 API 可供选择,而且它们都是跨平台的。我所知道的两个最全面的功能是:
两者都包含从图形到输入和音频例程的所有内容,无论是通过插件还是内置的。
此外,如果您觉得 C++ 中的标准库有点缺乏,请查看Boost以获得一些通用的跨平台甜头。
祝你好运。
C++ 是跨平台的。您似乎遇到的问题是您正在使用平台相关库。
我假设你真的在谈论 UI 组件——在这种情况下,我建议使用 GTK+、Qt 或 wxWindows 之类的东西——每个都有可以为不同系统编译的 UI 组件。
唯一的解决方案是让您找到和使用与平台无关的库。
而且,顺便说一句,cygwin 和 Wine 都不是仿真的——它们是在各自系统中找到的相同功能的 100% 本机实现。
一旦你意识到了陷阱,它实际上并不难。我目前正在编写的所有代码都在 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 行长。真的没什么。这包括处理字节序问题。
一些较低级别的东西将需要条件编译。例如,在 Windows 中,我使用临界区,但在 Linux 中,我需要使用 pthread_mutex。CriticalSection 被封装在一个类中,这个类有很多条件编译。但是,上层程序完全不知道,无论平台如何,类的功能都完全相同。
我可以告诉你的另一个秘密是:经常在所有平台上构建你的项目(尤其是在开始时)。当您将编译器问题扼杀在萌芽状态时,这会容易得多。不要等到完成开发后再尝试跨平台。
坚持使用跨平台的 ANSI C++ 和库,你应该没问题。
创建一些包含项目中所有特定于平台的代码的低级层。实现这一层的 2 个版本——一个用于 Windows,一个用于 Linux——具有相同的接口,并将它们构建为 2 个库。通过该界面访问项目中所有特定于平台的功能。
该层可以包含用于文件访问、打印、GUI 等的通用类。
使用该层的所有(现在非平台特定的)代码现在可以在 Windows 上编译一次,在 Linux 上编译一次。
在 Window 中编译它,然后在 Linux 中再次编译。除非您使用特定于平台的库,否则它应该可以工作。它不像Java,你编译一次就可以在任何地方工作。没有人为 C++ 制作过虚拟机,而且可能永远也不会。您用 C++ 编写的代码可以在任何平台上运行。你只需要先在每个平台上编译它。
建议:
对整数使用 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 可以成为你最好的朋友。还有你最大的敌人!(同时!)
当然可以。但是要尽早并经常编译和测试!
Linux 和 Windows 也有不同的数据模型。见文章:64 位程序开发中被遗忘的问题
标准 C++是在任何平台上都可以无错误编译的代码。尝试在 Windows 上使用Bloodshed Dev C++(而不是 VC++/Borland C++)。
由于 Bloodshed Dev C++ 确认了 C++ 标准,因此使用它编译的程序将在大多数情况下在 linux 上编译而不会出错。