2011-01-30 2 views
5

В настоящее время я использую функцию popen в коде, которая скомпилирована двумя компиляторами: MS Visual Studio и gcc (on linux). Возможно, мне захочется добавить gcc (на MinGW) позже.Самый стандартный способ выбора имени функции в зависимости от платформы?

Функция называется popen для GCC, но _popen для МСВС, поэтому я добавил следующее к моему исходному коду:

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

Это работает, но я хотел бы понять, существует ли стандартное решение такие проблемы (я вспоминаю аналогичный случай с stricmp/strcasecmp). В частности, я хотел бы понимать следующее:

  1. Действительно ли _MSC_VER правильный флаг, от которого зависит? Я выбрал его, потому что у меня создается впечатление, что среда Linux более «стандартная».
  2. Если я помещаю эти #define в какой-либо заголовочный файл, важно ли оно: i #include оно до или после stdio.h (для случая popen)?
  3. Если _popen определяется как сам макрос, есть ли шанс, что мой #define не получится? Должен ли я использовать «новый» токен, например, my_popen, по той или иной причине?
  4. Кто-то уже выполнил эту работу для меня и создал хороший файл «portability header», который я могу использовать?
  5. Что-нибудь еще, о чем я должен знать?

ответ

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 
1
  1. _MSC_VER является правильным макро для обнаружения компилятор MSVC. Вы можете использовать __GNUC__ для GCC.

  2. Если вы собираетесь использовать popen в качестве макро-ID, я предлагаю вам #include это после того, как из-за 3.

  3. Если вы #include это после stdio.h, он должен работать AFAIK, но лучше перестраховаться, чем потом сожалеть , нет? Назовите это portable_popen или что-то в этом роде.

  4. Многие проекты (включая некоторые из моих) имеют заголовок портативности, но обычно лучше сворачивать свои собственные. Я поклонник делать что-то самостоятельно, если у вас есть время. Таким образом, вы знаете детали своего кода (проще отлаживать, если все идет не так), и вы получаете код, который соответствует вашим потребностям.

  5. Не то, чтобы я знал. Я делаю это так все время, без проблем.

3
  1. Лучше проверить через окна-специфические определения (_WIN32 возможно), потому что MinGW не будет иметь его либо. popen() стандартизирован (это part of the Single UNIX® Specification v2)
  2. Нет; до тех пор, пока макрос определен до его первого использования, не имеет значения, если _popen() не определяется до более позднего времени.
  3. Нет; то, что у вас есть, хорошо, даже если _popen - это макрос.
  4. Это было сделано много раз, но я не знаю свободно лицензированной версии, которую вы можете использовать.
0

Вместо заканчиваясь с суматохой файлов, содержащими #ifdef .. #else .. #endif блоков, я бы предпочел вариант с использованием различных файлов для разных платформ:

  • поставить зависимые определения ОС в одном файле на платформе и #define макрос my_popen
  • #include этот файл в коде платформы-агностик
  • никогда не вызывает функции ОС напрямую, а созданный вами #define (т. my_popen)
  • в зависимости от вашей операционной системы, использовать различные заголовки для компиляции (например, config/windows/mydefines.h на окнах и config/linux/mydefines.h на Linux, поэтому установить включают путь соответствующий и всегда #include "mydefines.h")

Это намного чище подход, чем с ОС решение в самом источнике.

Если методы вы вызываете себя различались между окнами и Linux, решить, какой из них должен быть поведение вы используете (т.е. либо всегда поведение окна или всегда поведение Linux), а затем создать методы упаковки для добиться этого. Для этого вам потребуются не только два файла mydefines.h, но также и файлы myfunctions.c, которые находятся в каталоге config/OSTYPE.

Действовать таким образом, вы также получите преимущество, когда речь идет о дифф в Linux и версию Windows: вы можете просто дифф два файла в то время как делать диф на Линукс и окно блоках же файла может быть трудно ,

 Смежные вопросы

  • Нет связанных вопросов^_^