在C,C ++中检测Windows或Linux

我正在编写一个跨平台的程序。 我想要一个程序在Windows和Linux下运行,所以我有两个不同的代码段的两个平台。 如果操作系统是Windows,我想要第一个代码段运行; 如果是Linux,那么我想要第二个代码段运行。

所以我写了下面的代码,但是在Windows和Linux上构build时都会出错。 我该怎么办才能解决呢?

#ifdef __unix__ /* __unix__ is usually defined by compilers targeting Unix systems */ #define OS_Windows 0 #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #elif defined(_WIN32) || defined(WIN32) /* _Win32 is usually defined by compilers targeting 32 or 64 bit Windows systems */ #define OS_Windows 1 #include <windows.h> #include <stdio.h> #include <tchar.h> #define DIV 1048576 #define WIDTH 7 #endif int main(int argc, char *argv[]) { if(OS_Windows) { MEMORYSTATUSEX statex; statex.dwLength = sizeof (statex); GlobalMemoryStatusEx (&statex); _tprintf (TEXT("There is %*ld %% of memory in use.\n"), WIDTH, statex.dwMemoryLoad); } else if(!OS_Windows) // if OS is unix { char cmd[30]; int flag = 0; FILE *fp; char line[130]; int memTotal, memFree, memUsed; flag=0; memcpy (cmd,"\0",30); sprintf(cmd,"free -t -m|grep Total"); fp = popen(cmd, "r"); while ( fgets( line, sizeof line, fp)) { flag++; sscanf(line,"%*s %d %d %d",&TotalMem, &TotalUsed, &TotalFree); } pclose(fp); if(flag) printf("TotalMem:%d -- TotalUsed:%d -- TotalFree:%d\n",TotalMem,TotalUsed,TotalFree); else printf("not found\n"); } return 0; } 

一般这样做(或多或少):

 #ifdef _WIN32 #include <windows.h> #include <stdio.h> #include <tchar.h> #define DIV 1048576 #define WIDTH 7 #endif #ifdef linux #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #endif int main(int argc, char *argv[]) { #ifdef _WIN32 MEMORYSTATUSEX statex; statex.dwLength = sizeof (statex); GlobalMemoryStatusEx (&statex); _tprintf (TEXT("There is %*ld %% of memory in use.\n"), WIDTH, statex.dwMemoryLoad); #endif #ifdef linux char cmd[30]; int flag = 0; FILE *fp; char line[130]; int TotalMem, TotalFree, TotalUsed; flag=0; memcpy (cmd,"\0",30); sprintf(cmd,"free -t -m|grep Total"); fp = popen(cmd, "r"); while ( fgets( line, sizeof line, fp)) { flag++; sscanf(line,"%*s %d %d %d",&TotalMem, &TotalUsed, &TotalFree); } pclose(fp); if(flag) printf("TotalMem:%d -- TotalUsed:%d -- TotalFree:%d\n",TotalMem,TotalUsed,TotalFree); else printf("not found\n"); #endif return 0; } 

这样,只有linux的代码才会在linux平台上编译,只有windows代码才会在windows平台上编译。

你应该在代码中使用相同的#ifdef而不是if(OS_Windows)逻辑:

 #ifdef __unix__ ... #elif defined(_WIN32) || defined(WIN32) #define OS_Windows #endif int main(int argc, char *argv[]) { #ifdef OS_Windows /* Windows code */ #else /* GNU/Linux code */ #endif } 

您正在使用预处理器符号(仅在编译期间存在)混淆变量(运行时存在)。

在你做了像#define OS_Windows 1类的东西之后,你不能使用符号OS_Windows作为一个变量,并把它放在if() s …我的意思是,你可以,但是它会在编译期间扩展到if (1)

对于跨平台项目, 您必须使用#if#ifdef来确保编译器为给定的操作系统选择正确的代码部分并仅编译该代码。

就像是:

 void openWindow() { #if OS_Windows // windows-specific code goes here #else // linux-specific code #endif } 

我在这里看到了很多不同的解决方案,这让我感到不舒服…如果他们在Linux上工作,而不是在Windows或Windows上,而不是在Linux上工作? 如果他们只在一些编译器上工作会怎么样? 等等。

所以我找到了这个链接,我喜欢: http : //nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system

它看起来像是最好的(使用#ifdef,#endif等):

  • _WIN32 for Windows 32位
  • _WIN64为Windows 64位
  • __unix__ for Unix

你的基本策略是很有缺陷的。

通过在主函数中使用if,您可以选择在RUNTIME运行哪个代码块。 因此,即使编译为unix,编译器仍然需要为windows编写代码(因为不包含头文件,所以无法执行),反之亦然。

你需要#if在编译时将被评估,而不会尝试编译不相关的代码。

所以本质上你需要明白,如果在运行时评估你的定义为一个表达式,而#if在编译时计算这个预定义常量的值。