Как определить текущую операционную систему во время выполнения в C ++? - PullRequest
0 голосов
/ 28 июня 2018

Я хочу определить, в какой операционной системе запущен мой .exe, чтобы я мог выполнять определенные операции в зависимости от базовой операционной системы. Я хочу, чтобы это было только для Windows и Mac.

Ответы [ 3 ]

0 голосов
/ 28 июня 2018

Я хочу определить, в какой операционной системе запущен мой .exe

(обратите внимание, что в исполняемых файлах MacOSX традиционно нет суффикса .exe; это соглашение относится только к Windows)

Вы не можете обнаружить это в pure стандарте C ++ 11 во время выполнения (поэтому ваш вопрос технически не имеет смысла), потому что стандарт C ++ 11 n3337 не знает об операционных системах (некоторый исходный код C ++ может быть скомпилирован для чистого металла). Я бы рекомендовал условную компиляцию (например, #if) и использование специфических для операционной системы заголовков (и настройку автоматизации сборки для их обнаружения). Некоторые фреймворки C ++ ( boost , poco , Qt ....) могут быть полезны, но вам нужно выбрать один из них (они могут попытаться предоставить некоторые общие абстракции над несколькими ОС, но зло все еще в деталях, например пути к файлам все еще различны в Windows и в MacOSX).

MicroSoft Windows имеет собственный API , называемый WinAPI (который на практике используется только Windows. Возможно, однажды ReactOS *) 1034 * будет реализовывать большую часть этого API), задокументировано здесь . MacOSX более или менее соответствует POSIX , который является стандартным API для семейства операционных систем (но Windows не заботится об этом стандарте).

Если вы хотите узнать больше об ОС в целом (разумное занятие), прочитайте, например, Операционные системы: три простых компонента (свободно загружаемый учебник).

На практике исполняемый файл *1049*, скомпилированный из исходного кода C ++, специфичен для операционной системы, для которой он предназначен, и его формат файла также специфичен для некоторых ОС ( например, PE в Windows, ELF в Linux, Mach-O в MacOSX ...). Таким образом, исполняемый файл Windows не будет работать на MacOSX и наоборот (идея толстый двоичный код устарела в 2018 году). Вы, вероятно, изменили бы свою процедуру build (например, Makefile или cmake , ninja и т. Д.) Для ваша ОС. Эта процедура сборки может (и часто делает) передавать дополнительные флаги компиляции (например, какой-нибудь флаг -DBUILD_FOR_MACOSX compiler для вашего препроцессора , если выполняется сборка для MacOSX; тогда вы можете - в нескольких местах - использовать некоторую директиву препроцессора, такую ​​как #if BUILD_FOR_MACOSX в вашем исходном коде на C ++) для конкретной операционной системы. Вы даже можете настроить свою сборку так, чтобы в MacOSX скомпилировался некоторый файл for-macosx.cc C ++ (и его объектный файл, связанный с ним) с вашим программным обеспечением, но в Windows вы будете использовать другой файл for_windows.cc C ++. Иногда процедура сборки достаточно гибкая, чтобы автоматически определять во время сборки, что представляет собой операционная система (но как это сделать - другой вопрос. GNU autoconf может быть вдохновляющим).

После того, как ваша процедура сборки настроена (или имеет автоопределение) для вашей операционной системы, вы можете использовать препроцессор условные средства * от 1081 * до #include соответствующих системных заголовков и компилировать вызовы для конкретной ОС функции (такие как POSIX uname ), выполняющие запросы во время выполнения относительно ОС.

Некоторые компиляторы предопределяют набор символов препроцессора, и этот набор зависит от целевой операционной системы, процессора и вашего компилятора. Если вы используете GCC , вы можете создать некоторый пустой файл empty.cc и скомпилировать его с g++ -c -C -E -dM (возможно, также с другими соответствующими флагами, например -std=c++11), чтобы выяснить, какие набор символов препроцессора предопределен в вашем случае.

Подумайте над изучением исходного кода (включая процедуру сборки!) Некоторых кроссплатформенных свободных программ проектов (например, на github или где-то еще) для вдохновения. Вы также можете найти много ресурсов о многоплатформенных сборках C ++ (например, this one и many others).

0 голосов
/ 28 июня 2018

Чтобы решить эту проблему, вам нужно проверять как во время компиляции, так и во время выполнения. Вам понадобится разный код для разных систем. Вам понадобится код Windoze для проверки версии Windoze и код Mac для проверки версии Mac.

Вы собираетесь использовать

#if defined ()

во время компиляции, чтобы проверить, на каком из двух вы находитесь. Затем получите отдельный код для каждого, чтобы получить версию.

0 голосов
/ 28 июня 2018

Существуют различные способы сделать это, например, проверить наличие каталога C: \ Windows для обнаружения Windows (правка: если ОС вообще принимает такой путь, то это как минимум часть семейства DOS) , но ни один из них не является надежным. Вот один из способов (хотя это обман):

#include<boost/predef.h>

enum class OperatingSystem {
// ...
Windows
// ...
};

OperatingSystem DetectOperatingSystem()
{
#ifdef BOOST_OS_WINDOWS
return OperatingSystem::Windows;
#endif
}

Кроме того, если вы просто хотите, чтобы имя отображалось для пользователя, в системах POSIX вы можете использовать uname (2).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...