我目前在两个编译器编译的代码中使用popen
函数:MS Visual Studio和gcc(在linux上)。我可能想稍后添加gcc(在MinGW上)。
该函数对于gcc称为popen
,对于MSVS称为_popen
,因此我在源代码中添加了以下内容:
#ifdef _MSC_VER
#define popen _popen
#define pclose _pclose
#endif
这有效,但我想了解是否存在针对此类问题的标准解决方案(我回忆起stricmp
/ strcasecmp
的类似案例)。具体来说,我想了解以下内容:
_MSC_VER
是依赖的正确旗帜吗?我选择它是因为我的印象是linux环境“更标准”。#define
放在某个头文件中,是否#include
在stdio.h
之前或之后(对于popen
的情况)是否重要? _popen
定义为宏本身,我的#define
是否有可能失败?我应该使用像my_popen
这样的“新”令牌,因为这个或那个原因吗?答案 0 :(得分:3)
答案 1 :(得分:1)
_MSC_VER
是检测MSVC编译器的正确宏。您可以将__GNUC__
用于GCC。
如果您要使用popen
作为您的宏ID,我建议您#include
之后,因为3。
如果你在#include
之后stdio.h
,它应该可以使用AFAIK,但是比抱歉更安全,不是吗?称之为portable_popen
或其他。
许多项目(包括我的一些项目)都有一个可移植性标题,但通常最好自己滚动。如果你有时间的话,我是自己做事的粉丝。因此,您了解代码的详细信息(如果出现问题则更容易调试),并且您可以获得根据您的需求量身定制的代码。
不是我所知道的。我一直这样做,没有问题。
答案 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
块的混乱文件,而是使用不同平台使用不同文件的版本:
#define
宏my_popen
#include
此文件位于与平台无关的代码中#define
(即my_popen
)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上进行差异和相同的文件可能很难。