Написание кросс-платформенных приложений на C

Какие вещи следует иметь в виду при написании кросс-платформенных приложений в C? Целевые платформы: 32-разрядные ПК на базе ПК, Mac и Linux. Я особенно ищу тип универсальности, который Jungle Disk имеет в своем рабочем столе для настольных компьютеров (http://www.jungledisk.com/desktop/download.aspx)

Что такое подсказки и "gotchas" для этого типа разработки?

Ответ 1

В течение ряда лет я поддерживал сетевую библиотеку ANSI C, которая была перенесена на 30 различных ОС и компиляторов. В библиотеке не было компонентов GUI, что упростило работу. Мы завершили абстрагирование в выделенные исходные файлы любой подпрограммой, которая не была согласованной между платформами, и использовала #defines, где это необходимо, в этих исходных файлах. Это сохранил код, который был настроен на одну платформу, изолированную от основной бизнес-логики библиотеки. Мы также широко использовали typedefs и наши собственные специализированные типы, чтобы мы могли легко изменить их на платформу, если это необходимо. Это значительно облегчило перенос порта на 64-разрядные платформы.

Если вы хотите иметь компоненты GUI, я бы предложил посмотреть на инструментальные средства GUI, такие как WxWindows или Qt (которые являются как библиотеками С++).

Ответ 2

Старайтесь избегать зависимых от платформы #ifdefs, поскольку они, как правило, растут экспоненциально, когда вы добавляете новые платформы. Вместо этого попробуйте организовать исходные файлы как дерево с независимым от платформы кодом в корневом каталоге и зависимым от платформы кодом на "листах". Существует хорошая книга по этой теме, Многоплатформенное управление кодами. Пример кода в нем может выглядеть устаревшим, но идеи, описанные в книге, по-прежнему чрезвычайно важны.

Ответ 3

В дополнение к ответу Кайла я настоятельно рекомендую не пытаться использовать подсистему Posix в Windows. Он реализован на абсолютном минимальном уровне, так что Microsoft может заявить о поддержке "Posix" в тике. Возможно, кто-то там действительно использует его, но я никогда не сталкивался с ним в реальной жизни.

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

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

Ответ 4

Постарайтесь писать столько, сколько вы можете с помощью 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.

Ответ 5

В настоящее время существует довольно мало портативных библиотек, которые я использовал в прошлом

1) glib и gtk +

2) libcurl

3) libapr

Они охватывают почти каждую платформу, поэтому они являются чрезвычайно полезным инструментом.

Posix отлично подходит для Unices, но я сомневаюсь, что это отлично по окнам, кроме того, у нас нет никаких вещей для портативных графических интерфейсов.

Ответ 6

XVT имеет API-интерфейс с интерфейсом GUI CRO, который имеет зрелые 15+ лет и находится поверх собственных оконных оконных окон. См. WWW.XVT.COM.

Они поддерживают как минимум LINUX, Windows и MAC.

Ответ 7

Я также рекомендую разделить код для разных платформ на разные модули/деревья вместо ifdefs.

Также я рекомендую заранее проверить, каковы различия в ваших платформах и как можно их абстрагировать. Например. это некоторые связанные с ОС материалы (например, раздражающие CR, CRLF, LF в текстовых файлах) или аппаратные средства. Например. предыдущая упомянутая совместимость posix не останавливает вас от

int c;
fread(&c, sizeof(int), 1, file);

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