是否有任何宏来确定我的代码是否正在编译到Windows?

时间:2009-01-10 02:30:03

标签: c++ c operating-system c-preprocessor

我想检测我正在编译的操作系统是否是Windows。我可以检查一个简单的宏来验证吗?

11 个答案:

答案 0 :(得分:34)

[编辑:我假设您要使用编译时宏来确定您所在的环境。也许你想确定你是在Linux下运行Wine还是用Windows而不是Windows运行,但一般情况下,你的编译器针对的是特定的环境,那就是Windows(DOS)或者不是,但它很少(从来没有) ?)两者。]

某些编译器提供宏来指示Windows构建环境。但是这些因编译器而异,甚至在Windows上的相同编译器上如果目标环境专门为windows。通常它是__WIN32__,但并非总是如此。

#if defined (__WIN32__)
  // Windows stuff
#endif

有时它可以是_WIN32__CYGWIN32__,或者可能只是编译器指示符(_MSC_VER)。

如果您知道要构建的环境(来自makefile),那么您通常可以在命令行中传递#define,例如“g++ -D __WIN32__ yourfile.c”。

A little more info here

答案 1 :(得分:19)

有许多不同的方法可以检测编译,主机和运行时环境。一切都取决于你想知道什么。有三种类型的环境:

  • 构建:这是编译程序的环境。
  • 主机:这是运行程序的环境。
  • 目标:如果是代码生成工具(例如编译器),则会生成生成的代码。

如果您是交叉编译,那么构建和主机环境可能完全不同(这在构建嵌入式应用程序时很常见,但在构建桌面/服务器应用程序时不常见),而且通常无法在用于编译它的系统上运行已编译的二进制文件。否则,主机环境必须与构建环境兼容:例如,在XP上构建将在Vista上运行的应用程序。

C预处理器宏不能用于告诉您主机系统的详细信息(即您正在运行的内容);他们只能告诉你编译代码的内容。在Windows的情况下,两个最重要的宏是:

  • _WIN32 表示Win32 API可用。 告诉您使用的是哪个编译器,实际上_WIN32在使用Cygwin的GCC和MinGW的GCC时都已定义。因此,不要使用_WIN32来确定是否使用Visual Studio进行编译。
  • _MSC_VER 告诉您正在使用Microsoft Visual C / C ++编译该程序。好吧,差不多。使用英特尔的C ++编译器时,_MSC_VER 也是,该编译器旨在替代Visual C ++。

Visual Studio文档中描述了许多其他宏。

如果您想知道您正在使用的Windows的确切版本,则必须使用运行时函数,例如GetVersion()(如其他答案中所述)。

如果您确切地告诉我们您要检查的内容,您可能会得到更具体的答案。

答案 2 :(得分:15)

% touch foo.C ; g++ -dM -E foo.C

可以很好地列出[机器特定的] g ++编译器为您自动定义的所有宏(#define)。

微软的编译器可能有类似的东西......

答案 3 :(得分:8)

这三行将帮助您进行检测,首先我们或大多数预定义窗口提示一起成为一个OS_WIN宏定义:

#if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
#define OS_WIN
#endif

然后你可以使用预处理器ifdef:

来检查它
#ifdef OS_WIN
//Windows specific stuff
#else
//Normal stuff
#endif

答案 4 :(得分:4)

如果您正在运行MS Windows目标代码,可以调用GetVersion()或GetVersionEx()以获取更多信息,并识别您正在运行的Windows变体。

有关详细信息,请参阅MSDN信息。

http://msdn.microsoft.com/en-us/library/ms724451(VS.85).aspx

答案 5 :(得分:4)

这个东西适用于visual studio 2012,和 其他cgwin的g ++编译器。 切割并粘贴它 但这通常很薄 它只是检测Windows操作系统。 只需应用量化: 如果不赢 然后* inux :D享受

#include <string>
#include <iostream>
#include <fstream>
#include <cstdlib>
Using namespace std;


int main(){    
    char chCap;    int i = 0;
    const int MAX_BUFFER = 70; 
    char buffer[MAX_BUFFER];

    string cmd="ver";   
    FILE *stream = _popen(cmd.c_str(), "r");

    if (0 != stream){
        while (!feof(stream)){  
            //One way is here
            //chCap = fgetc(stream);
            //cout << chCap;
            //buffer[i++] = chCap;

            //This one seams better
            fgets(buffer, MAX_BUFFER, stream);      
        }
        _pclose(stream);
    }       
    cout << endl;
    cout << buffer << endl;

    //The op sys detection starts here
    string opSys(buffer);   //char array to string
    if("Microsoft" == opSys.substr(0,9)){
        cout << "You are in a Microsoft envornment " << endl;
    }
    system("pause");
    return 0;    
}

答案 6 :(得分:3)

到目前为止提到的链接在编译时表示信息。您可以在编译时在这些代码段中设置标志。

但是,我认为你所要求的更像是“我在哪个版本的Windows下运行?”而不是“我编译为在Windows下运行吗?”我希望这是一个正确的假设。

在C#下,它相对简单。您可以引用System.Environment.OSVersion,然后查看“Platform”。

但是,你问的是C ++。你用的是什么编译器?这对于如何检查操作系统的版本有很大的不同,因为没有单一的标准来获取这些信息(我发现了)。

在Visual C ++下,使用Google查找有关GetVersion / GetVersionEx的信息。两者都将为您提供包含有关运行该程序的当前Windows版本的信息的结构。

答案 7 :(得分:3)

MSVC ++编译器(不是windows.h)为所有版本定义_WIN32,因此它是一个更安全的宏来检查。 MinGW gcc编译器也是如此。任何针对Win32 的交叉编译环境都应该设置它。

答案 8 :(得分:2)

其实我会选择环境。 getenv()是一个标准的库函数,因此可能是唯一可行的可移植方式。诀窍在于确定哪些变量对于所有操作系统都是唯一的。 Windows具有应设置的ComSpec,appdata,Windir,systemroot和systemdrive。您还可以为WINDOWS或WINNT创建路径变量,但这可能不准确。我不是Linux shell / Solaris / MacOS专家,所以其他人可能会告诉你这些操作系统中存在哪些“标准”环境变量。 CygWin也可能会引起一些问题。

答案 9 :(得分:1)

它可能取决于您正在使用的编译器,但请尝试:

#ifdef WIN32
...
#endif

答案 10 :(得分:1)

如上所列的宏将告诉您,如果您的程序是已编译(或者更确切地说, for )Windows计算机,如果在Windows机器上正在运行

如果您编写的内容完全与平台无关(即它只处理打开/读取/处理/写入)文件流...您将不得不进行一些测试,例如打开一个在计算机运行Windows时应该存在的文件。如果你的程序只使用标准的stdio,数学等,那就是这种情况。

否则,如果您的代码包含Windows特定的系统调用,则它根本不会在任何其他平台上运行。

您可以编写一些宏,如:

#define RUNNING_ON_WINDOWS ( ... some test )

只是不要将它用于条件编译,即:

if (RUNNING_ON_WINDOWS) {
  ... 
} else 
   printf("Windows Required\n");