在C, c++中检测Windows或Linux
Detect Windows or Linux in C, C++
我正在写一个跨平台程序。我希望这个程序在Windows和Linux下都能运行,所以我为这两个平台准备了两个不同的代码段。如果操作系统是Windows,我希望第一个代码段运行;如果是Linux,那么我希望运行第二个代码段。
所以我写了下面的代码,但它得到一个错误,同时在Windows和Linux上构建。我该怎么解呢?
#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," ",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:%dn",TotalMem,TotalUsed,TotalFree);
else
printf("not foundn");
}
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," ",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:%dn",TotalMem,TotalUsed,TotalFree);
else
printf("not foundn");
#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
}
我在这里看到了很多不同的解决方案,这让我感到不舒服…如果它们可以在Linux上运行而不能在Windows上运行,或者在Windows上运行而不能在Linux上运行呢?如果它们只在某些编译器上工作呢?等。
所以我找到了这个链接,我喜欢:https://web.archive.org/web/20191012035921/http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system
看起来这些是最好的(使用#ifdef, #endif等):
-
_WIN32
for Windows 32位或64位 -
_WIN64
仅适用于Windows 64位
__unix__
for Unix你混淆了变量(存在于运行时)和预处理器符号(只存在于编译期间)。
在你做了像#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
}
你的基本策略存在严重缺陷。
通过在main函数中使用if,您可以选择在运行时运行的代码块。因此,即使为unix编译,编译器仍然必须为windows构建代码(这是失败的,因为头文件不包括在内),反之亦然。
您需要的是#if,它将在编译时求值,并且不会尝试编译不相关的代码。
所以本质上你需要理解if在运行时计算你的定义作为一个表达式,而#if在编译时计算预定义常量的值。
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 在Linux for Windows上编译C++代码时出错
- 在Linux和C++中的Windows上,散列字符串值会产生不同的输出
- 函数在Windows或Linux上运行时表现不同
- 如何在CPP中创建应该在Windows和Linux上运行的套接字?
- CMake WxWidgets项目成功地在Linux上构建,但没有在Windows上构建
- 声明C++具有动态大小的数组类型在 Linux 中工作正常,但不能在 Windows 中工作
- 如何在 Linux for Windows 上通过 MinGW 构建静态 ICU 的 Boost
- 在Linux上使用Clang / OLLVM交叉编译helloworld Windows可执行文件时的问题
- 分段 Linux Ubuntu 中的 g++ 错误,但在 Windows 中的 g++/MingW 中,在 C++ 中打
- 在 Linux 群集上运行 Windows C++代码
- Windows 和 Linux 之间的相对路径分辨率差异?
- 将 Genteruse 从 Linux 转换为 Windows
- g++ 9.2.1 (Linux) 会导致 seg 错误,但 Windows 上的代码块不会
- 绕过 Windows 中的 __declspec(dllimport) 到 Linux 项目的转换
- Google Play游戏服务可以用于PC游戏吗?(Windows/Linux/OSX)
- 用于在运行时记录调用堆栈的库(Windows/Linux)
- (clang / llvm-mc / lld) hello world (x86-64 Windows & Linux)
- 使用Qt(Windows/Linux)从远程目标获取ping
- Windows Linux c++ 编译问题:"no matching function for call"