2011-01-30 19 views
5

Obecnie używam funkcji popen w kodzie, który jest kompilowany przez dwa kompilatory: MS Visual Studio i gcc (na Linuksie). Mogę później dodać gcc (na MinGW).Najbardziej standardowy sposób wyboru nazwy funkcji w zależności od platformy?

Funkcja nazywa popen dla gcc, ale _popen dla MSVS, tak I dodaje następujące do mojego kodu źródłowego:

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

To działa, ale chciałbym zrozumieć, czy istnieje standardowe rozwiązanie takie problemy (pamiętam podobny przypadek z stricmp/strcasecmp). W szczególności chciałbym zrozumieć:

  1. Czy to jest flaga z prawej strony, na której można polegać? Wybrałem to, ponieważ mam wrażenie, że środowisko Linux jest "bardziej standardowe".
  2. Jeśli umieściłem te #define w pliku nagłówka, czy ważne jest, czy I #include to przed czy po stdio.h (dla przypadku popen)?
  3. Jeśli _popen jest zdefiniowane jako samo makro, czy istnieje ryzyko, że mój #define zakończy się niepowodzeniem? Czy zamiast tego powinienem użyć "nowego" tokena, takiego jak my_popen, z tego czy innego powodu?
  4. Czy ktoś już wykonał dla mnie tę pracę i wykonał dobry plik nagłówka przenośności, którego mogę użyć?
  5. Coś jeszcze powinienem wiedzieć?

Odpowiedz

1

Sposób, w jaki to robisz jest w porządku (z #ifdef itp.), Ale testowane makro nie jest. popen jest czymś, co zależy od systemu operacyjnego, a nie od kompilatora.

pójdę coś jak

#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 jest poprawne wykrycie makro do kompilatora MSVC. Możesz użyć __GNUC__ dla GCC.

  2. Jeśli masz zamiar użyć popen jako makro ID, proponuję #include go później, bo od 3.

  3. Jeśli #include to po stdio.h, to powinno działać AFAIK, ale lepiej dmuchać na zimne nie? Nazwij to portable_popen lub coś w tym stylu.

  4. Wiele projektów (w tym niektóre z moich) ma nagłówek przenośności, ale zwykle lepiej jest przetaczać własne. Jestem fanem robienia rzeczy samemu, jeśli masz czas. Dzięki temu znasz szczegóły swojego kodu (łatwiejsze do debugowania, jeśli coś pójdzie nie tak), a otrzymasz kod dostosowany do Twoich potrzeb.

  5. Nie to, co wiem. Robię takie rzeczy przez cały czas, bez problemów.

3
  1. Lepiej sprawdzić, czy okna specyficzne define (_WIN32 chyba) ponieważ MinGW nie będzie musiał go albo. popen() jest standaryzowany (jest to part of the Single UNIX® Specification v2)
  2. Nie; tak długo, jak makro jest zdefiniowane przed pierwszym użyciem, nie ma znaczenia, że ​​_popen() nie zostanie zdefiniowane później.
  3. Nie; to, co masz, jest w porządku, nawet jeśli _popen jest makro.
  4. Dokonano tego wiele razy, ale nie znam wersji swobodnie licencjonowanej, której można użyć.
0

Zamiast kończąc Nieporządek pliki zawierające #ifdef .. #else .. #endif bloki, wolałbym wersję przy użyciu różnych plików na różnych platformach:

  • umieścić definicje zależne od systemu operacyjnego w jednym pliku na platformie i #define makro my_popen
  • #include ten plik w Twoim kodzie-agnostycznym kodzie
  • nigdy nie wywołaj bezpośrednio funkcji systemu operacyjnego, ale utworzona przez ciebie #define (tj. my_popen)
  • w zależności od używanego systemu operacyjnego, należy użyć różnych nagłówków do kompilacji (np config/windows/mydefines.h na okna i config/linux/mydefines.h na Linuksie, więc ustawić zawierać ścieżkę właściwą i zawsze #include "mydefines.h")

to jest znacznie czystsze podejście niż o OS decyzja w samym źródle.

Jeśli metod Dzwonisz zachowywać się różnią między Windows i Linux, zdecydować, który z nich będzie zachowanie używasz (tj albo zawsze okna zachowanie lub zawsze zachowanie Linux), a następnie utworzyć metody owijki osiągnąć to. Do tego potrzebne będą nie tylko dwa pliki mydefines.h, ale także pliki myfunctions.c, które znajdują się w katalogach config/OSTYPE.

Robi to w ten sposób, można również uzyskać korzyści, jeśli chodzi o diff linux i wersję systemu Windows: można po prostu diff dwa pliki robiąc diff na Linux i Windows bloków samym pliku może być trudne .

Powiązane problemy