根据平台选择功能名称的最标准方法是什么?

时间:2011-01-30 16:45:06

标签: c portability popen

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

该函数对于gcc称为popen,对于MSVS称为_popen,因此我在源代码中添加了以下内容:

#ifdef _MSC_VER
#define popen _popen
#define pclose _pclose
#endif

这有效,但我想了解是否存在针对此类问题的标准解决方案(我回忆起stricmp / strcasecmp的类似案例)。具体来说,我想了解以下内容:

  1. _MSC_VER是依赖的正确旗帜吗?我选择它是因为我的印象是linux环境“更标准”。
  2. 如果我将这些#define放在某个头文件中,是否#includestdio.h之前或之后(对于popen的情况)是否重要?
  3. 如果将_popen定义为宏本身,我的#define是否有可能失败?我应该使用像my_popen这样的“新”令牌,因为这个或那个原因吗?
  4. 有人已经为我做了这个工作并制作了一个好的“便携头”文件,我可以使用吗?
  5. 我还应该注意什么?

4 个答案:

答案 0 :(得分:3)

  1. 最好检查特定于Windows的定义(也许是_WIN32)因为mingw也没有。 popen()是标准化的(它是part of the Single UNIX® Specification v2
  2. 否;只要宏在第一次使用之前定义,如果直到稍后才定义_popen()并不重要。
  3. 否;即使_popen是一个宏,你所拥有的也很好。
  4. 已经多次完成,但我不知道你可以使用的免费许可版本。

答案 1 :(得分:1)

  1. _MSC_VER是检测MSVC编译器的正确宏。您可以将__GNUC__用于GCC。

  2. 如果您要使用popen作为您的宏ID,我建议您#include之后,因为3。

  3. 如果你在#include之后stdio.h,它应该可以使用AFAIK,但是比抱歉更安全,不是吗?称之为portable_popen或其他。

  4. 许多项目(包括我的一些项目)都有一个可移植性标题,但通常最好自己滚动。如果你有时间的话,我是自己做事的粉丝。因此,您了解代码的详细信息(如果出现问题则更容易调试),并且您可以获得根据您的需求量身定制的代码。

  5. 不是我所知道的。我一直这样做,没有问题。

答案 2 :(得分:1)

你这样做的方式很好(#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

答案 3 :(得分:0)

我不想使用包含#ifdef .. #else .. #endif块的混乱文件,而是使用不同平台使用不同文件的版本:

  • 将每个平台的操作系统相关定义放在一个文件中,#definemy_popen
  • #include此文件位于与平台无关的代码中
  • 从不直接调用操作系统功能,但是您创建的#define(即my_popen
  • 取决于您的操作系统,使用不同的标头进行编译(例如,在Windows上为config/windows/mydefines.h,在Linux上为config/linux/mydefines.h,因此请设置适当的包含路径并始终#include "mydefines.h"

这比在源本身中做出操作系统决策要简洁得多。

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

这样做,你也可以在扩展linux和windows版本时获得优势:你可以简单地对两个文件进行区分,同时在linux上进行差异和相同的文件可能很难。