Условная компиляция в C ++ на основе операционной системы - PullRequest
6 голосов
/ 25 мая 2009

Я хотел бы написать кроссплатформенную функцию на C ++, которая содержит системные вызовы. Какие флаги условной компиляции я могу проверить, чтобы определить, для какой операционной системы код компилируется? Мне интересны в основном Windows и Linux, использующие Visual Studio и GCC.

Я думаю, это должно выглядеть примерно так:

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

#ifdef LINUX
    LinuxSystemCall();
#endif

#ifdef WINDOWS
    WindowsSystemCall();
#endif

    // Other code
}

Ответы [ 4 ]

7 голосов
/ 25 мая 2009

Нет стандартного способа сделать это. Может быть возможно отключить определенные макросы, которые определены для платформы. Например, _WIN32 будет определяться в Windows и почти наверняка не в Linux. Однако я не знаю ни одного соответствующего макроса Linux.

Поскольку вы используете отдельные компиляторы, из этого следует, что у вас есть отдельные среды сборки. Почему бы просто не добавить макрос самостоятельно? Visual Studio и GCC поддерживают определение макросов из командной строки, поэтому просто определите их.

7 голосов
/ 25 мая 2009

Мой gcc (4.3.3) определяет следующие предопределенные макросы для Linux:

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

Под VC ++ (и многими другими компиляторами Win32) также есть пара предопределенных макросов, идентифицирующих платформу, особенно _WIN32. Дополнительная информация: http://msdn.microsoft.com/en-us/library/b0084kay(VS.80).aspx

5 голосов
/ 25 мая 2009

Я всегда стараюсь не допускать особенностей платформы в основной код, делая это таким образом

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
}

Теперь в windows_platform.h и linux_platform.h вы вводитеdef system_related_type для собственного типа и либо #define platform_SystemCall в качестве собственного вызова, либо создаете небольшую функцию-оболочку, если аргумент, установленный с одной платформы на другую слишком разные.

Если системные API для конкретной задачи сильно различаются между платформами, вам может потребоваться создать собственный API версии, который разделяет разницу. Но по большей части между различными API-интерфейсами в Windows и Linux существуют довольно прямые сопоставления.

Вместо того, чтобы полагаться на какой-то конкретный компилятор #define для выбора платформы, я #define BUILD_PLATFORM xxx в файле проекта или make-файле, так как в любом случае они должны быть уникальными для платформы.

0 голосов
/ 30 июня 2010

Вот что я использую. Работает под Visual Studio 2008 и 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  
...