在 C、C++ 中检测 Windows 或 Linux
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8666378/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Detect Windows or Linux in C, C++
提问by Ronin
I am writing a cross platform program. I want this one program to run under both Windows and Linux, so I have two different code segments for the two platforms. If the OS is Windows, I want the first code segment to run; if it's Linux, then I want the second code segment to run.
我正在编写一个跨平台程序。我希望这个程序可以在 Windows 和 Linux 下运行,所以我有两个不同的代码段用于两个平台。如果操作系统是 Windows,我希望第一个代码段运行;如果是 Linux,那么我希望运行第二个代码段。
So I wrote the following code, but it gets an error while building both on Windows and on Linux. What should I do to solve it?
所以我写了下面的代码,但是在 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,"#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,"#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
}
",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;
}
",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;
}
采纳答案by user703016
It's generally done like this (more or less):
它通常是这样完成的(或多或少):
void openWindow() {
#if OS_Windows
// windows-specific code goes here
#else
// linux-specific code
#endif
}
This way, only code for linux will be compiled while on a linux platform, and only windows code will be compiled on a windows platform.
这样,在linux平台上只编译linux的代码,在windows平台上只编译windows的代码。
回答by Zaur Nasibov
You should use the same #ifdef
instead of if(OS_Windows)
logic in your code:
您应该在代码中使用相同的#ifdef
而不是if(OS_Windows)
逻辑:
回答by Kos
You are confusing variables (which exist in run-time) with preprocessor symbols (which only exist during compilation).
您将变量(存在于运行时)与预处理器符号(仅在编译期间存在)混淆。
After you do something like #define OS_Windows 1
, you can't use the symbol OS_Windows as a variable and put it inside if()
s... I mean, you can, but it will be expanded during compilation to if (1)
.
你喜欢的东西后#define OS_Windows 1
,你不能使用符号OS_Windows作为一个变量,并把它里面if()
小号......我的意思是,你可以,但它在编译期间进行扩展if (1)
。
For a cross-platform project, you have to use #if
or #ifdef
to make sure that the compiler chooses a correct part of code for a given OS and compiles only that.
对于跨平台项目,您必须使用#if
或#ifdef
确保编译器为给定的操作系统选择正确的代码部分并仅编译该部分。
Something like:
就像是:
##代码##回答by Elemental
Your basic strategy is deeply flawed.
你的基本策略存在严重缺陷。
By using the if in the main function you are selecting which chunk of code to run at RUNTIME. Thus even if compiling for unix the compiler still has to build the code for windows (which it is failing to do because the header files are not included) and visa versa.
通过在主函数中使用 if,您可以选择在 RUNTIME 运行的代码块。因此,即使为 unix 编译,编译器仍然必须为 windows 构建代码(由于不包含头文件,它无法做到),反之亦然。
You instead required #if which will be evaluated at compile time and will not attempt to compile irrelevant code.
相反,您需要 #if ,它将在编译时进行评估,并且不会尝试编译不相关的代码。
So in essence you need to understand that if evaluates your define as an expression at runtime whereas #if evaluates the value of the predefined constant at compile time.
因此,本质上您需要了解 if 在运行时将您的定义计算为表达式,而 #if 在编译时计算预定义常量的值。
回答by Andrew
I see a lot of varying solutions here, which makes me uncomfortable... What if they work on Linux but not Windows or on Windows but not Linux? What if they only work on some compilers? Etc.
我在这里看到了很多不同的解决方案,这让我很不舒服……如果它们在 Linux 但不能在 Windows 上工作,或者在 Windows 但不能在 Linux 上怎么办?如果它们只适用于某些编译器怎么办?等等。
So I found this link, which I like: http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system
所以我找到了这个我喜欢的链接:http: //nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system
It looks like these are best (using #ifdef, #endif, etc.):
看起来这些是最好的(使用 #ifdef、#endif 等):
_WIN32
for Windows 32 bit_WIN64
for Windows 64 bit__unix__
for Unix
_WIN32
适用于 Windows 32 位_WIN64
适用于 Windows 64 位__unix__
用于 Unix