C++ 在C、C和x2B中检测Windows或Linux+;
我正在写一个跨平台的程序。我希望这一个程序同时在Windows和Linux下运行,因此我有两个不同的代码段用于这两个平台。如果操作系统是Windows,我希望运行第一个代码段;如果是Linux,那么我希望运行第二个代码段 因此,我编写了以下代码,但在Windows和Linux上构建时都会出错。我该怎么解决它C++ 在C、C和x2B中检测Windows或Linux+;,c++,c,windows,linux,C++,C,Windows,Linux,我正在写一个跨平台的程序。我希望这一个程序同时在Windows和Linux下运行,因此我有两个不同的代码段用于这两个平台。如果操作系统是Windows,我希望运行第一个代码段;如果是Linux,那么我希望运行第二个代码段 因此,我编写了以下代码,但在Windows和Linux上构建时都会出错。我该怎么解决它 #ifdef __unix__ /* __unix__ is usually defined by compilers targeting Unix s
#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 uuuuuuuuuuuu/*uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu通常由针对unix系统的编译器定义*/
#定义OS_Windows 0
#包括
#包括
#包括
#包括
#elif定义(_WIN32)|定义(WIN32)/*_WIN32通常由针对32位或64位Windows系统的编译器定义*/
#定义OS_Windows 1
#包括
#包括
#包括
#定义分区1048576
#定义宽度7
#恩迪夫
int main(int argc,char*argv[])
{
如果(操作系统窗口)
{
Memorystaturex statex;
statex.dwLength=sizeof(statex);
GlobalMemoryStatusEx(&statex);
_tprintf(TEXT(“有%*ld%%个内存在使用中。\n”),
宽度,statex.dwMemoryLoad);
}
else if(!OS_Windows)//如果操作系统是unix
{
char-cmd[30];
int标志=0;
文件*fp;
字符行[130];
int memTotal、memFree、memUsed;
flag=0;
memcpy(cmd,“\0”,30);
sprintf(cmd,“free-t-m | grep Total”);
fp=popen(cmd,“r”);
而(fgets(生产线、生产线尺寸、fp))
{
flag++;
sscanf(行“%*s%d%d%d”、&TotalMem、&TotalUsed、&TotalFree);
}
pclose(fp);
国际单项体育联合会(旗)
printf(“TotalMem:%d--TotalUsed:%d--TotalFree:%d\n”,TotalMem,TotalUsed,TotalFree);
其他的
printf(“未找到”);
}
返回0;
}
您应该在代码中使用相同的#ifdef
而不是if(操作系统窗口)
逻辑:
#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
}
通常是这样做的(或多或少):
\ifdef\u WIN32
#包括
#包括
#包括
#定义分区1048576
#定义宽度7
#恩迪夫
#ifdef linux
#包括
#包括
#包括
#包括
#恩迪夫
int main(int argc,char*argv[])
{
#ifdef_WIN32
Memorystaturex statex;
statex.dwLength=sizeof(statex);
GlobalMemoryStatusEx(&statex);
_tprintf(TEXT(“有%*ld%%个内存在使用中。\n”),
宽度,statex.dwMemoryLoad);
#恩迪夫
#ifdef linux
char-cmd[30];
int标志=0;
文件*fp;
字符行[130];
int TotalMem、TotalFree、TotalUsed;
flag=0;
memcpy(cmd,“\0”,30);
sprintf(cmd,“free-t-m | grep Total”);
fp=popen(cmd,“r”);
而(fgets(生产线、生产线尺寸、fp))
{
flag++;
sscanf(行“%*s%d%d%d”、&TotalMem、&TotalUsed、&TotalFree);
}
pclose(fp);
国际单项体育联合会(旗)
printf(“TotalMem:%d--TotalUsed:%d--TotalFree:%d\n”,TotalMem,TotalUsed,TotalFree);
其他的
printf(“未找到”);
#恩迪夫
返回0;
}
这样,在linux平台上只编译linux代码,在windows平台上只编译windows代码。您将变量(在运行时存在)与预处理器符号(仅在编译期间存在)混淆 执行类似于
#定义OS_Windows 1
的操作后,不能将符号OS_Windows用作变量并将其放入if()
s中。。。我的意思是,您可以,但是在编译过程中,如果(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在编译时计算预定义常量的值。我在这里看到很多不同的解决方案,这让我感到不舒服。。。如果它们在Linux而不是Windows上工作,或者在Windows而不是Linux上工作,该怎么办?如果它们只在某些编译器上工作呢?等等
所以我找到了这个链接,我喜欢:
看起来这些是最好的(使用#ifdef、#endif等):
\u WIN32
适用于Windows 32位
\u WIN64
适用于Windows 64位
- 用于unix的unix
什么类型的错误?发生这种情况是因为编译器正在查找MemoryStatuex
,因为如果(OS_Windows)
检查不是预处理器检查,它会在运行时发生,因此,在if
项下的所有内容都必须编译。@RRR请记住勾选答案旁边最能解决您的问题的勾号,这就是我们如何将问题标记为已解决的。也请用你的其他问题来做:-存在跨平台的C++库,比如Qt。通过它的QtCore模块,您可以在Linux、MacOSX和Windows之间移植非图形化应用程序的代码。@RRR我保证memcpy(cmd,“\0”,30)
不会达到您期望的效果。使用memset(cmd,'\0',30)
任何值得使用的优化编译器都会删除if(0)
块。@Dave不幸的是,这并没有真正的帮助,因为编译器无法优化它无法编译的任何内容。我的意思是,问题不是无关的符号;它是不存在的。@Dave同样,任何称职的编译器在-O0
时也不会删除if(0)
。thankzzz。。。。你是一个救生员。@Cicada要使编译此代码更改为int memTotal,memFree
void openWindow() {
#if OS_Windows
// windows-specific code goes here
#else
// linux-specific code
#endif
}