6

Chciałbym napisać funkcję międzyplatformową w C++, która zawiera wywołania systemowe. Jakie flagi warunkowej kompilacji mogę sprawdzić, aby określić, dla którego systemu operacyjnego jest kompilowany kod? Interesuje mnie głównie Windows i Linux, używając Visual Studio i GCC.Kompilacja warunkowa w C++ na podstawie systemu operacyjnego

myślę, że powinno to wyglądać mniej więcej tak:

void SomeClass::SomeFunction() 
{ 
    // Other code 

#ifdef LINUX 
    LinuxSystemCall(); 
#endif 

#ifdef WINDOWS 
    WindowsSystemCall(); 
#endif 

    // Other code 
} 

Odpowiedz

7

Moja gcc (4.3.3) definiuje następujące Linux związanych z predefiniowanych makr:

$ gcc -dM -E - < /dev/null | grep -i linux 
#define __linux 1 
#define __linux__ 1 
#define __gnu_linux__ 1 
#define linux 1 

Pod VC++ (i wiele innych Win32 kompilatory) istnieje również kilka wstępnie zdefiniowanych makr identyfikujących platformę, w szczególności _WIN32. Dalsze szczegóły: http://msdn.microsoft.com/en-us/library/b0084kay(VS.80).aspx

+3

Jest haczyka gdy ma do czynienia z Win32/Win64 warunkowej kompilacji - podczas kompilacji dla Win64 można zauważyć, że _WIN32 definiuje więc próba przed _WIN64 przed przetestować (!) przeciwko _WIN32 –

7

Nie ma standardowego sposobu, aby to zrobić. Może być możliwe wyłączenie określonych makr zdefiniowanych na platformę. Na przykład _WIN32 zostanie zdefiniowany w Windowsie i prawie na pewno nie w Linuksie. Jednak nie znam żadnego odpowiedniego makra Linuxa.

Ponieważ używasz oddzielnych kompilatorów, oznacza to, że masz oddzielne środowiska kompilacji. Dlaczego nie wystarczy samodzielnie dodać makro? Zarówno Visual Studio, jak i GCC obsługują definiowanie makr z wiersza poleceń, więc po prostu je definiuj.

+0

Chciałbym użyć do większości typowych makr do tego, mam nadzieję, domyślne zdefiniowane przez same kompilatory. Wygląda na to, że _WIN32 i Linux wystarczą dla moich celów. –

+1

Oczywiście, ale czy to zadziała dla BSD i innych smaków UNIX? Naprawdę najlepiej jest go zdefiniować (w makefile, kompilacji systemu itp.) Samemu. Jeśli jesteś niezadowolony, przynajmniej chroń swój kod za pomocą czegoś takiego jak #ifdef _WIN32 #define PLATFORM "Windows" #endif następnie #fifefef PLATFORM #error PLATFORM undefined - sprawdź konfigurację #endif – plinth

5

Zawsze staram się zachować specyfikę platformy z głównego kodu robiąc to w ten sposób

platform.h:

#if BUILD_PLATFORM == WINDOWS_BUILD 
#include "windows_platform.h" 
#elif BUILD_PLATFORM == LINUX_BUILD 
#include "linux_platform.h" 
#else 
#error UNSUPPORTED PLATFORM 
#endif 

someclass.c:

void SomeClass::SomeFunction() 
{ 
    system_related_type t; 
    // Other code 
    platform_SystemCall(&t); 
    // Other code 
} 

Teraz w windows_platform.h i linux_platform.h ty typedef system_related_type na typ natywny i #define platform_SystemCall jako połączenie natywne lub utwórz małą funkcję opakowania , jeśli argument ustawiony z jednej platformy na drugą jest zbyt inny.

Jeśli interfejsy API systemu dla określonego zadania znacznie różnią się między platformami, może być konieczne utworzenie własnego interfejsu API wersji, który dzieli różnicę. Ale w większości przypadków istnieją dość bezpośrednie odwzorowania między różnymi interfejsami API w systemach Windows i Linux.

Zamiast polegać na konkretnym kompilatorze #define, aby wybrać platformę, ja #define BUILD_PLATFORM w pliku projektu lub makefile, ponieważ i tak muszą one być unikalne dla platformy.

0

Oto, czego używam. Działa pod Visual Studio 2008 i MinGW:

#ifdef __GNUC__ 
    #define LINUX 
#else 
    #define WINDOWS 
#endif 

#ifdef WINDOWS 
    #include "stdafx.h" 
#else 
    #include <stdlib.h> 
    #include <string.h> 
    #include <stdio.h> 
    #include <ctype.h> 
    #include <assert.h> 
    #include <malloc.h> 
#endif 
Powiązane problemy