Написание кроссплатформенных приложений на C
Какие вещи следует иметь в виду при написании кроссплатформенных приложений на C? Целевые платформы: 32-битный ПК на базе Intel, Mac и Linux. Я особенно ищу тип универсальности, который есть у Jungle Disk в настольной версии USB ( http://www.jungledisk.com/desktop/download.aspx)
Каковы советы и "ошибки" для этого типа развития?
8 ответов
В течение нескольких лет я поддерживал сетевую библиотеку ANSI C, которая была портирована на 30 различных ОС и компиляторов. В библиотеке не было никаких компонентов GUI, что облегчало работу. В итоге мы абстрагировали в выделенные исходные файлы любую подпрограмму, которая не согласовывалась на разных платформах, и в соответствующих случаях использовали #defines в этих исходных файлах. Это держало код, который был приспособлен для каждой платформы, изолированным от основной бизнес-логики библиотеки. Мы также широко использовали typedefs и наши собственные выделенные типы, чтобы при необходимости мы могли легко менять их для каждой платформы. Это сделало перенос на 64-битные платформы довольно простым.
Если вы ищете компоненты GUI, я бы посоветовал взглянуть на наборы инструментов GUI, такие как WxWindows или Qt (обе библиотеки C++).
Старайтесь избегать зависимых от платформы #ifdefs, так как они имеют тенденцию к экспоненциальному росту при добавлении новых платформ. Вместо этого, попытайтесь организовать ваши исходные файлы в виде дерева с независимым от платформы кодом в корне и зависимым от платформы кодом на "листьях". Есть хорошая книга на эту тему, Multi-Platform Code Management. Пример кода в нем может выглядеть устаревшим, но идеи, описанные в книге, все еще блестяще необходимы.
В дополнение к ответу Кайла я настоятельно рекомендую не пытаться использовать подсистему Posix в Windows. Он реализован на абсолютно минимальном уровне, так что Microsoft может заявить о "поддержке Posix" в поле для отметки в листе функций. Возможно, кто-то там действительно использует это, но я никогда не сталкивался с этим в реальной жизни.
Можно, конечно, написать кросс-платформенный код на C, нужно просто знать о различиях между платформами и тестировать, тестировать, тестировать. Модульные тесты и решение CI (непрерывная интеграция) будут иметь большое значение для обеспечения работы вашей программы на всех ваших целевых платформах.
Хороший подход состоит в том, чтобы изолировать системно-зависимые компоненты максимум в одном или нескольких модулях. Предоставьте системно-независимый интерфейс от этого модуля. Затем создайте все остальное поверх этого модуля, чтобы он не зависел от системы, для которой вы компилируете.
XVT имеют кроссплатформенный API-интерфейс GUI C, который существует более 15 лет и находится на вершине встроенных оконных сборок. Смотрите WWW.XVT.COM.
Они поддерживают как минимум LINUX, Windows и MAC.
Вы можете использовать NAppGUI как для консольных, так и для настольных приложений. SDK использует ANSI-C, и ваш код будет работать в Windows / macOS / Linux.
Это бесплатно и с открытым исходным кодом.
Я также рекомендую разделить код для разных платформ на разные модули / деревья вместо ifdefs.
Также я рекомендую заранее проверить, в чем различия между вашими платформами и как вы можете их абстрагировать. Например, это некоторые вещи, связанные с ОС (например, раздражающие CR,CRLF,LF в текстовых файлах) или аппаратные вещи. Например, предыдущая совместимость с posix не мешает вам
int c;
fread(&c, sizeof(int), 1, file);
Но на разных аппаратных платформах структура внутренней памяти может быть совершенно разной (endianess), что заставляет вас использовать функции преобразования на некоторых целевых платформах.
Попробуйте написать столько, сколько вы можете с POSIX. Mac и Linux изначально поддерживают POSIX, и в Windows есть система, которая может его запускать (насколько я знаю - я никогда не использовал его). Если ваше приложение графическое, Mac и Linux поддерживают библиотеки X11 (изначально Linux, Mac через X11.app), и существует множество способов заставить приложения X11 работать в Windows.
Однако, если вы ищете истинное многоплатформенное развертывание, вам, вероятно, следует переключиться на язык, такой как Java или Python, который способен запускать одну и ту же программу на нескольких системах практически без изменений.
Изменить: я только что скачал приложение и посмотрел на файлы. Похоже, что он имеет двоичные файлы для всех трех платформ в одном каталоге. Если вас беспокоит то, как писать приложения, которые можно перемещать с компьютера на компьютер без потери настроек, вам, вероятно, следует записать всю свою конфигурацию в файл в том же каталоге, что и исполняемый файл, и не трогать реестр Windows или создавать какие-либо точечные каталоги в домашняя папка пользователя, который запускает программу на Linux или Mac. А что касается создания бинарного дистрибутива Linux, 32-битный POSIX/X11, вероятно, будет самым безопасным выбором. Я не уверен, что JungleDisk использует, поскольку я в настоящее время на Mac.
Существует довольно мало переносимых библиотек, только примеры, с которыми я работал в прошлом
1) Глеб и ГТК +
2) libcurl
3) libapr
Они охватывают практически каждую платформу и поэтому являются чрезвычайно полезным инструментом.
Posix хорош для Unices, но я сомневаюсь, что он отлично подходит для Windows, к тому же у нас нет ничего для портативных графических интерфейсов.