编写跨平台C ++代码(Windows,Linux和Mac OSX)

时间:2010-09-02 12:37:02

标签: c++ cross-platform

这是我在C ++中编写任何稍微复杂的东西的第一次尝试,我正在尝试构建一个可以从Objective-C和.NET应用程序接口的共享库(好吧,那部分后来...... 。)

我的代码是 -

#ifdef TARGET_OS_MAC
  // Mac Includes Here
#endif

#ifdef __linux__
  // Linux Includes Here
  #error Can't be compiled on Linux yet
#endif

#ifdef _WIN32 || _WIN64
  // Windows Includes Here
  #error Can't be compiled on Windows yet
#endif

#include <iostream>

using namespace std;

bool probe(){
  #ifdef TARGET_OS_MAC
    return probe_macosx();
  #endif
  #ifdef __linux__
    return probe_linux();
  #endif
  #ifdef _WIN32 || _WIN64
    return probe_win();
  #endif
}

bool probe_win(){
  // Windows Probe Code Here
  return true;
}

int main(){

  return 1;
}

我有一个编译器警告,只是untitled: In function ‘bool probe()’:untitled:29: warning: control reaches end of non-void function - 但我也非常感谢人们可以建议如何更好地编写这类代码......

5 个答案:

答案 0 :(得分:46)

而不是重复自己并再次写入相同的#ifdef ....行再次,你可能更好地在标题中声明probe()方法,并提供三个不同的源文件,一个用于每个平台。这样做的好处是,如果添加平台,则无需修改所有现有源,只需添加新文件即可。使用构建系统选择适当的源文件。

示例结构:

include/probe.h
src/arch/win32/probe.cpp
src/arch/linux/probe.cpp
src/arch/mac/probe.cpp

警告是因为probe()没有返回值。换句话说,三个#ifdef都不匹配。

答案 1 :(得分:32)

我将解决这个特定的功能:

bool probe() {
#ifdef TARGET_OS_MAC
  return probe_macosx();
#elif defined __linux__
  return probe_linux();
#elif defined _WIN32 || defined _WIN64
  return probe_win();
#else
#error "unknown platform"
#endif
}

以if-elif-else链的方式编写它会消除错误,因为如果没有有效的return语句或命中#error就无法编译。

(我相信WIN32是针对32位和64位Windows定义的,但如果没有查找,我无法明确告诉你。这样可以简化代码。)


不幸的是,你不能使用#ifdef _WIN32 || _WIN64:请参阅http://codepad.org/3PArXCxo以获取示例错误消息。您可以使用特殊的仅预处理定义的运算符,如上所述。


关于根据功能或整个文件(如suggested)拆分平台,您可能想要也可能不希望这样做。它将取决于您的代码的详细信息,例如平台之间共享的内容以及您(或您的团队)最适合保持功能同步的内容,以及其他问题。

此外,您应该在构建系统中处理平台选择,但这并不意味着您不能使用预处理器:对每个平台使用有条件定义的宏(由makefile或构建系统定义)。实际上,这通常是模板和内联函数最实用的解决方案,这使得它比尝试消除预处理器更灵活。它与整个文件方法完美结合,因此您仍然可以在适当的地方使用它。

您可能希望使用单个配置标头,将所有各种特定于编译器和平台的宏转换为您控制的众所周知的宏。或者您可以通过构建系统将-DBEAKS_PLAT_LINUX添加到编译器命令行 - 以定义该宏(请记住使用宏名称的前缀)。

答案 2 :(得分:5)

在您编译代码时似乎没有定义TARGET_OS_MAC__linux___WIN32_WIN64

所以它就像你的代码一样:

bool probe(){
}

这就是编译器抱怨到达非void函数结束的原因。没有return条款。


此外,对于更一般的问题,这是我在开发多平台/架构软件/库时的指导原则:

避免特定情况。尝试编写与操作系统无关的代码。

在处理系统特定的东西时,尝试将东西包装成“不透明”的类。例如,如果您正在处理文件(Linux和Windows上的不同API),请尝试创建一个File类,它将嵌入所有逻辑并提供通用接口,无论操作系统如何。如果其中一个操作系统上没有某个功能,请处理它:如果该功能对特定的操作系统没有意义,那么通常什么都不做。

简而言之:#ifdef越少越好。无论您的代码多么可移植,请在发布之前在每个平台上进行测试。

祝你好运;)

答案 3 :(得分:1)

警告是因为如果实际上没有定义任何定义,那么探测函数中没有return。对此的修复是默认的return

答案 4 :(得分:1)

除了上面的未完成选项之外,为了添加更多内容,编译器已知指令__linux___WIN32,其中TARGET_OS_MAC指令不是,这可以是使用__APPLE__解决。资料来源:http://www.winehq.org/pipermail/wine-patches/2003-July/006906.html