Подтвердить что ты не робот

Являются ли приложения С++ межплатформенными?

Одна из первых вещей, которые я изучил в качестве студента, заключалась в том, что приложения на С++ не работают в разных операционных системах. Недавно я прочитал, что Qt-приложения на С++ работают повсеместно. Так, что происходит? Являются ли приложения С++ кросс-платформенными или нет?

4b9b3361

Ответ 1

  1. Исходный код совместим. Если я скомпилирую исходный код, он будет работать везде?

  2. Совместимость API/ABI. Предоставляет ли ОС интерфейс своим компонентам таким образом, чтобы код мог их понять?

  3. Бинарная совместимость. Может ли код работать на целевом хосте?

Совместимый с исходным кодом

C++ - это стандарт, который определяет, как структуры, память, файлы могут быть прочитаны и записаны.

#include <iostream>
int main( int argc, char ** argv )
{
     std::cout << "Hello World" << std::endl;
}

Код, написанный для обработки данных (например, grep, awk, sed), как правило, кроссплатформенный.

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

Такие библиотеки, как qt или wxWidgets имеют реализации для нескольких платформ и позволяют программировать для qt вместо Windows или iOS, в результате чего результат совместим с обеими.

Проблема этих анонимизирующих библиотек заключается в том, что они лишают некоторые конкретные преимущества платформы X в интересах единообразия между платформами.

Примерами этого могут служить Windows с использованием функции WaitForMultipleObjects, которая позволяет вам ожидать возникновения различных типов событий, или функция fork в UNIX, которая позволяет двум копиям вашего процесса выполняться со значительным общее состояние. В пользовательском интерфейсе формы выглядят и ведут себя немного по-другому (например, средство выбора цвета, максимизация, минимизация, возможность отслеживать мышь за пределами вашего окна, поведение жестов).

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

Библиотека C sqlite является широко кроссплатформенным кодом, но ее низкоуровневый ввод-вывод зависит от платформы, поэтому она может гарантировать целостность базы данных (что данные действительно записываются на диск).

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

Совместимость API/ABI

Различные версии UNIX и Windows имеют некоторую форму совместимости друг с другом. Это позволяет двоичному файлу, созданному для одной версии ОС, работать на других версиях ОС.

В UNIX выбор вашей машины сборки определяет совместимость. Наименьшей версией ОС, которую вы хотите поддерживать, должна быть ваша сборочная машина, и она будет создавать двоичные файлы, совместимые с последующими второстепенными версиями, до тех пор, пока они не внесут критические изменения (не рекомендуется использовать библиотеку).

В Windows и Mac OS X вы выбираете SDK, который позволяет вам ориентироваться на набор ОС с теми же проблемами, что и при критических изменениях.

В Linux каждая ревизия ядра ABI несовместима с любой другой, и модули ядра необходимо перекомпилировать для каждой ревизии ядра.

Бинарная совместимость

Это способность процессора понимать код. Это сложнее, чем вы думаете, поскольку чипы x64 могут (в зависимости от поддержки ОС) выполнять код x86.

Обычно программа C++ упакована в контейнер (исполняемый файл PE, формат ELF), который используется операционной системой для распаковки разделов кода и данных и для загрузки библиотек. Это делает конечную программу несовместимыми как в двоичном (тип кода), так и в API (формат контейнера).

Также сегодня, если вы компилируете приложение для Windows x86 (нацеленное на Windows 7 в Visual Studio 2015), код может не исполниться, если процессор не имеет инструкций SSE2 (около 10 лет CPU).

Наконец, когда Apple перешла с PowerPC на x86, они предоставили слой эмуляции, который позволял старому коду PowerPC запускаться в эмуляторе на платформе x86.

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

Даже если ваша платформа не способна выполнять набор команд, она может быть эмулирована и вести себя совместимо.

Ответ 2

Стандартная С++ - это кросс-платформа в смысле "писать один раз, компилировать в любом месте", но не в смысле "компилировать один раз, работать где угодно".

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

Однако вы не можете скомпилировать свою программу на своем компьютере, отправить двоичный файл и затем ожидать, что он будет работать с другими объектами. (По крайней мере, не в общем случае, конечно, можно распространять двоичные файлы из кода С++ при определенных условиях, но они зависят от фактической цели. Это широкое поле.)


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

Некоторые библиотеки, такие как Qt и Boost, доступны во многих системах (эти два в Linux, Mac и Windows, по крайней мере, я полагаю), поэтому ваш код останется кросс-платформой, если вы их используете.

Ответ 3

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

Это не "компилировать один раз, работать в любом месте с соответствующей виртуальной машиной", как это делает Java или С#, но "писать один раз, компилировать в любом месте с соответствующей средой", как это делал C все время.

Поскольку стандартная библиотека не предоставляет все, что вам может понадобиться, вам необходимо искать сторонние библиотеки для обеспечения этой функциональности. Определенные структуры - например Boost, Qt, GTK +, wxWidgets и т.д. - могут обеспечить это. Поскольку эти структуры написаны таким образом, что они компилируются на разных платформах, вы можете достичь межплатформенных функций в вышеупомянутом смысле.


Есть разные вещи, о которых нужно знать, если вы хотите, чтобы ваш код на С++ был кросс-платформенным.

Очевидным является источник, который делает предположение на типы данных. Ваш long может быть 32-битным здесь и 64-битным. Выравнивание типа данных и заполнение структуры могут отличаться. Существуют способы "играть в нее безопасно", например, size_t/size_type/uint16_t typedefs и т.д., И способы ошибиться, например wchar_t и std::wstring. Требуется дисциплина и некоторый опыт, чтобы "понять это правильно".

Не все компиляторы созданы равными. Вы не можете использовать все последние возможности языка С++ или использовать библиотеки, которые полагаются на эти функции, если вам требуется, чтобы ваш источник компилировался на других компиляторах на С++. Сначала проверьте таблицу совместимости.

Еще одна вещь endianess. Только один пример, когда вы пишете поток целых чисел для файла на одной платформе (например, x86 или x86_64), а затем читаете его снова на другой платформе (например, POWER), вы можете столкнуться с проблемами. Зачем вам писать целые числа в файл? Ну, UTF-16 - целые числа... опять же, дисциплина и некоторый опыт проделали большой путь к тому, чтобы сделать это довольно безболезненным.

После того, как вы проверили все эти поля, вам нужно убедиться в доступности библиотек, на которой вы основываете свой код. Хотя std:: является безопасным (но см. "Не все компиляторы созданы равными" выше), то, что невинно, как boost::, может стать проблемой, если вы смотрите за пределы основного направления. (Я помог ребятам Boost исправить один или два шоу-стоппера относительно AIX/Visual Age в прошлые годы просто потому, что у них не было доступа к этой платформе для тестирования новых выпусков...)

О, и следите за различными схемами лицензирования. Некоторые структуры, которые улучшают ваши кросс-платформенные возможности, такие как Qt или Cygwin, привязаны к их строкам. Это не означает, что они не являются большой помощью в правильных обстоятельствах, просто чтобы вы знали о требованиях к копированию/патентованных лицензиях.


Все, что сказано, Wine ( "Wine не является эмуляцией" ), что делает исполняемые файлы, скомпилированные для Windows, запускаемыми множество Unix-подобных систем (Linux, OS X, * BSD, Solaris). Существуют определенные ограничения в его возможностях, но они все время улучшаются.

Ответ 4

Да. Нет. Может быть. Что такое кросс-платформенный код на С++? Кросс-платформенный код С++ - это такой код, который может быть скомпилирован в разных операционных системах без необходимости изменения.

Это означает, что если вы явно используете любые зависящие от платформы заголовки, ваш код больше не является межплатформенным. Qt решает эту проблему следующим образом: они предоставляют оболочку для всего, что зависит от платформы. Например, представьте, что вы используете QFile для открытия/чтения/записи файла. Ваш код выглядит как

QFile file(filename);
file.open(QFile::ReadOnly);
//other stuff

Вы можете скомпилировать этот код под любой ОС, если у вас есть подходящий компилятор и библиотеки Qt для этой ОС. Код, скрытый под QFile, будет использовать соответствующие функции OS-обработки файлов, но это не должно вас беспокоить.

Кроме того, если вы используете только стандартную библиотеку, ваш код может быть скомпилирован везде, где присутствует компилятор С++.

Однако уже скомпилированные приложения не являются кросс-платформенными в том смысле, что, скажем, приложения Java - например, вы не можете скомпилировать приложение для Windows, а затем запустить в Linux, вам придется перекомпилируйте свой код под Linux.

Ответ 5

С++ - это язык программирования. Текст. Таким образом, он нигде не работает.

Соответствие стандартного кода на С++, как ожидается, будет вести себя одинаково на любой платформе; "кросс-платформенный", если хотите. Написание (строго) соответствие кода на С++ требует педантизма, потому что некоторые часто сделанные предположения имеют зависимости от деталей, которые являются окончательными для реальной реализации, и это унаследовано от целей, к которым стремится цель С++.

Заметьте, что мы все еще говорим о коде на С++, а не о программах на С++. Действительно, когда мы переходим к термину "программа", у нас больше нет гарантий, потому что мы больше не говорим о С++; скорее, выход компилятора. Здесь переносимость начинает исчезать: исполняемый формат, ISA, ABI, низкоуровневые процедуры и т.д.
Можете ли вы на это положиться? Если вы не можете, тогда вам нужно интегрировать свою С++-программу в среду, в которой она будет работать, путем перекомпиляции или использования элементов, специфичных для платформы.

Ответ 6

С++ является кросс-платформенным. Вы можете использовать его для создания приложений, которые будут работать во многих разных операционных системах.

Что не является кросс-платформенным, это компиляторы, которые переводят С++ в объектный код. Насколько мне известно, ни один компилятор не имеет всех необходимых функций, поэтому, когда вы используете его для компиляции программы на С++, он будет автоматически запускаться в Windows, Linux и Mac OS.

Qt Creator интегрирован с несколькими компиляторами и имеет автоматизацию построения. Это позволяет легко переключаться между различными настройками и целевыми платформами. Он обеспечивает поддержку для создания, запуска и развертывания приложений на С++ не только для настольных систем, но и для мобильных устройств.