C 根据平台选择函数名的最标准方法是什么?

C 根据平台选择函数名的最标准方法是什么?,c,portability,popen,C,Portability,Popen,我目前正在使用由两个编译器编译的代码中的popen函数:MS Visual Studio和gcc(在linux上)。我可能想稍后添加gcc(在MinGW上) 对于gcc,函数名为popen,但是对于MSV,函数名为\u popen,因此我在源代码中添加了以下内容: #ifdef _MSC_VER #define popen _popen #define pclose _pclose #endif 这是可行的,但我想了解是否存在针对此类问题的标准解决方案(我记得stricmp/stracecmp

我目前正在使用由两个编译器编译的代码中的
popen
函数:MS Visual Studio和gcc(在linux上)。我可能想稍后添加gcc(在MinGW上)

对于gcc,函数名为
popen
,但是对于MSV,函数名为
\u popen
,因此我在源代码中添加了以下内容:

#ifdef _MSC_VER
#define popen _popen
#define pclose _pclose
#endif
这是可行的,但我想了解是否存在针对此类问题的标准解决方案(我记得
stricmp
/
stracecmp
)。具体而言,我想了解以下几点:

  • \u MSC\u VER
    是依赖的正确标志吗?我选择它是因为我觉得linux环境“更标准”
  • 如果我将这些
    #定义
    #放在某个头文件中,那么在
    stdio.h
    之前还是之后包含
    是否重要(对于
    popen
  • 如果将
    \u popen
    定义为宏本身,我的
    \define
    是否有可能失败?出于这样或那样的原因,我应该使用“新”令牌,如
    my_popen
  • 是否有人已经为我做了这项工作,并制作了一个好的“可移植性头文件”供我使用
  • 还有什么我应该知道的吗
  • \u MSC\u VER
    是检测MSVC编译器的正确宏。您可以对GCC使用
    \uuuu GNUC\uuu

  • 如果您打算使用
    popen
    作为宏ID,我建议您将
    #包含在它之后,因为3

  • 如果你在stdio.h后面加上,它应该可以正常工作,但安全总比抱歉好,不是吗?把它叫做便携式的popen或者别的什么东西

  • 许多项目(包括我的一些项目)都有一个可移植性标题,但通常最好是自己滚动。如果你有时间,我很喜欢自己做事。这样,您就知道了代码的细节(如果出现问题,调试就更容易了),并获得了适合您需要的代码

  • 据我所知没有。我一直在做这样的事情,没有任何问题

  • 最好检查特定于windows的定义(可能是WIN32),因为mingw也不会有它。popen()是标准化的(它是
  • 没有;只要宏是在第一次使用之前定义的,那么直到以后才定义_popen()并不重要
  • 没有;即使popen是一个宏,您所拥有的也很好
  • 这已经做了很多次了,但我不知道有没有免费授权的版本可以使用

  • 使用
    #ifdef
    等进行测试的方式很好,但测试的宏却不是这样
    popen
    取决于您的操作系统,而不是编译器

    我喜欢这样的东西

    #if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 2)
    /* system has popen as expected */
    #elif defined(YOUR_MACRO_TO DETECT_YOUR_OS)
    # define popen _popen
    # define pclose _pclose
    #elif defined(YOUR_MACRO_TO DETECT_ANOTHER_ONE)
    # define popen _pOpenOrSo
    # define pclose _pclos
    #else
    # error "no popen, we don't know what to do"
    #endif
    

    与其以包含
    #ifdef
    的凌乱文件结束。
    #else
    #endif
    块,我更喜欢为不同平台使用不同文件的版本:

    • 将依赖操作系统的定义放在每个平台的一个文件中,并定义一个宏
      my\u popen
    • #将此文件包含在平台无关代码中
    • 永远不要直接调用操作系统函数,而是调用您创建的
      #define
      (即
      my\u popen
    • 根据您的操作系统,使用不同的头进行编译(例如windows上的
      config/windows/mydefines.h
      ,linux上的
      config/linux/mydefines.h
      ,因此设置适当的包含路径,并始终
      #包含“mydefines.h”
    这是一种比将操作系统决策放在源代码中更干净的方法

    如果您调用的方法在windows和linux之间的行为不同,请确定您使用的行为(即始终windows行为或始终linux行为),然后创建包装器方法以实现此目的。为此,您不仅需要两个
    mydefines.h
    文件,还需要存放在
    config/OSTYPE
    目录中的
    myfunctions.c
    文件

    这样做,在区分linux和windows版本时,您还可以获得优势:您可以简单地区分两个文件,而在相同的文件的linux和windows块上进行区分可能很困难