Как написать программу для Android на c

Обновлено: 31.10.2024

В этом руководстве я представлю еще один вариант разработки для вашего следующего проекта Android, который идеально подходит для команд с устаревшим кодом или существующими знаниями в области C и C++. Android Native Development Kit (NDK) является частью официального набора инструментов Google, и мы рассмотрим, когда NDK может быть полезен и как его использовать в приложении для Android.

Что такое NDK?

NDK – это набор инструментов, который позволяет разрабатывать приложения для Android с использованием C, C++ и других собственных языков программирования, компилируя код в приложения, которые могут работать на устройствах Android. Использование NDK, как правило, не рекомендуется, поскольку приложения могут столкнуться с падением производительности, проблемами совместимости, сложностью отладки и снижением гибкости. Что гарантирует NDK, так это увеличение сложности приложения и возможности подключения за счет взаимодействия с собственным кодом.

Предыдущие заявления могут звучать обескураживающе, но есть хорошие варианты использования NDK. Сюда входят приложения с интенсивными вычислениями, такие как игры, игровые движки, обработка сигналов и моделирование физики. Еще один хороший вариант использования — повторное использование существующих библиотек, написанных на C/C++. Это означает, что вы можете использовать большую коллекцию собственных библиотек кода, доступных в Интернете.

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

Использование NDK

Студия Android

Если у вас его еще нет, загрузите Android Studio, официальную интегрированную среду разработки от Google.

Пакет NDK

Android Studio включает только инструменты и SDK по умолчанию, поэтому загрузите и установите пакет NDK отдельно. Есть два способа сделать это. Первый и самый простой вариант — автоматическая установка на вкладке Инструменты SDK. Это большая загрузка (~ 1 ГБ), поэтому убедитесь, что у вас хорошее подключение к Интернету и/или терпение.

Инструменты SDK< бр />

После завершения загрузки или клонирования импортируйте пример проекта Android (с именем android-project) из папки SDL в Android Studio, приняв значения по умолчанию на экранах импорта. После создания проекта может возникнуть проблема с синхронизацией, связанная с отсутствующей версией SDK. Чтобы решить эту проблему, откройте диспетчер SDK и загрузите соответствующую версию SDK для проекта. В данном случае Android 3.1 (уровень API 12). Установите флажок Показать сведения о пакете, чтобы показать эту версию, так как она помечена как устаревшая. Можно использовать более новую версию, но пока давайте остановимся на android-12, чтобы не усложнять задачу.

Android 12< бр />

После установки SDK проект должен синхронизироваться без ошибок, отображая сообщение BUILD SUCCESSFUL в консоли. Если вы обнаружите какие-либо другие ошибки, сообщите мне об этом в комментариях.

Gradle Console< бр />

Грейдл

Android Studio использует Gradle, систему автоматизации сборки с открытым исходным кодом для управления проектами и их выходными данными. Большая часть конфигурации проекта происходит внутри файлов gradle. Давайте добавим в проект немного ручной настройки. Откройте build.gradle (модуль приложения) и добавьте следующий код под свойством buildToolsVersion:

Это скроет нативный код в обозревателе проекта, который поможет вручную собрать SDL, и нативный код с помощью ndk-build , который находится в папке ndk-bundle. Создание нативного кода вручную является более надежным методом по сравнению с автоматическими сборками с использованием Android Studio и Gradle. Поддержка Gradle для NDK все еще является экспериментальной, и не все варианты использования обрабатываются.

Gradle модуля приложения

Символическая ссылка

Давайте создадим символическую ссылку внутри папки app/src/main/jni/ проекта. Назовите его SDL и укажите папку SDL, загруженную или клонированную ранее. Папку SDL можно скопировать напрямую, но этот метод менее эффективен и подвержен ошибкам. Исходные файлы скрыты в Android Studio, поэтому их необходимо открыть вручную во внешнем редакторе, чтобы внести следующие изменения.

Android.mk

Android.mk — это простой make-файл, описывающий исходный код проекта и общие библиотеки для системы сборки. В уже импортированном проекте эти make-файлы имеются по умолчанию, но с минимальной необходимой конфигурацией. Давайте внесем изменения в файл Android.mk основного приложения. Этот файл находится в папке app/src/main/jni/src.Найдите строку YourSourceHere.c и замените ее на main.c .

Приложение.mk

Файл make Application.mk содержит конфигурацию, общую для всех модулей, и влияет на то, как строится весь проект. Добавьте следующую строку в Application.mk внутри папки app/src/main/jni/:

Этот параметр свойства сообщает ndk-build, что минимальной целевой версией является Android 3.1, и указывает проекту на соответствующие файлы заголовков. Еще один параметр, который необходимо изменить в Application.mk, — это дополнительные целевые платформы, использующие свойство APP_ABI. Выберите платформы из списка ниже или добавьте их все:

  • arm64-v8a
  • армеаби
  • armeabi-v7a
  • мипс
  • мипс64
  • x86
  • x86_64

Добавление поддержки всех этих платформ расширит охват приложения, но приведет к увеличению размера APK-файла.

main.c

Последний шаг — добавить пользовательский код, который инициализирует SDL и вызывает его функции, чтобы проверить, работает ли проект. Для удобства воспользуемся этим файлом main.c, загрузив его в папку app/src/main/jni/src.

Создание и запуск

Заключение

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

Я хотел бы услышать ваш опыт и мнения об использовании кода C и C++ с Android NDK в комментариях ниже.


C – широко известный язык программирования. Создан Деннисом Ритчи в период с 1969 по 1973 год в Bell Labs. С тех пор он стал одним из самых широко используемых языков программирования всех времен.

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

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

Android основан на ядре Linux, поэтому определенно можно компилировать и запускать программы C/C++ на Android.

C является кросс-платформенным, поэтому программа C, написанная для Windows, может работать в Linux (и Android) и наоборот.

Специальное примечание: вам может быть интересно, почему я включил C++ вместо того, чтобы сосредоточиться только на C.
Причина в том, что C++ на самом деле разрабатывался как надмножество языка программирования C, и в настоящее время никто не занимается его сборкой. компилятор, специфичный только для C. Таким образом, компилятор для C также может компилировать программы на C++

Если вы новичок в программировании на C или хотите начать изучать программирование на C, я рекомендую прочитать нашу статью Baby Steps in C Programming

Итак, продолжая разговор, давайте перейдем к поиску способов запуска программ C/C++ в Android

CXXDroid, разработанный IIEC, представляет собой полноценную интегрированную среду разработки C/C++ для Android. Он имеет довольно мощные функции, перечисленные ниже

  • Полный автономный компилятор — интернет не нужен
  • Диспетчер пакетов доступен для получения библиотек
  • Мощный редактор
  • Интерпретатор C/C++ (REPL)
  • Примеры кода

CXXDroid — запуск программ C на Android

CXXDroid из Play Маркета

Если вы хотите учиться и экспериментировать с C/C++, я рекомендую использовать CXXDroid.

Установить из : Play Store

Разработанная Антоном Смирновым, CppDroid – это довольно известная и хорошо известная среда разработки C/C++ для Android, надежная и надежная, имеющая множество функций,

  • Полный автономный компилятор C/C++ – Интернет не требуется
  • Умная подсветка синтаксиса
  • Автоматический отступ
  • Темы

CppDroid — запуск программ C и Cpp на Android

CppDroid из Play Маркета

Если вам нужна полная рабочая среда разработки C/C++, я рекомендую использовать CppDroid.
Но прямо сейчас есть один недостаток: он не обновлялся в Play Store с 17 августа 2017 года

Установить из : Play Store

Termux, комплексное решение, которое также упоминалось в нашей предыдущей статье Python для Android — запуск программ Python в Android

Как уже упоминалось в предыдущей статье, это эмулятор терминала для Android, что означает, что с его помощью мы можем запускать любые Linux (почти любые 😉) программы на Android.

редактирование сценариев C в vim

Чтобы установить и использовать компилятор C/C++ в Termux (в Termux clang — это компилятор C/C++),

  1. Загрузите и установите Termux из: Play Store
  2. После установки выполните эту команду pkg install clang
  3. После успешной установки clang вы можете компилировать сценарии C/C++.

Пример:
clang hello.c
После того, как вы получите исполняемый файл a.out, который вы можете запустить, используя ~$./a.out

Для редактирования и создания сценариев C/C++ вы можете использовать VIM внутри termux, который можно установить с помощью pkg install vim
Или вы можете использовать QuickEdit

Если вы новичок в мире программирования и никогда не использовали приложения командной строки, я бы не рекомендовал вам использовать Termux, вместо этого используйте CXXDroid или CppDroid.

Друзья, на этом пока все, увидимся в следующий раз. Есть вопросы, предложения? Дайте мне знать в комментариях ниже 👇

Если вам нравится моя работа (мои статьи, истории, программы, исследования и многое другое), купите мне кофе ☕ 🤗

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

Я пытаюсь разработать/перенести игру на Android, но она написана на C, а Android поддерживает Java, но я уверен, что должен быть способ добавить туда приложение на C, кто-нибудь знает способ выполнить это?

G1 по умолчанию не разрешает root-доступ, и существует множество ограничений в отношении того, что может быть выполнено за пределами среды «Android». У меня не было бы большой надежды найти способ выполнять нативный код из Android.

20 ответов 20

Для тех, кто приходит к этому через Google, обратите внимание, что начиная с SDK 1.6 Android теперь имеет официальный собственный SDK.

Android NDK – это набор инструментов, который позволяет вам реализовывать части вашего приложения в собственном коде с использованием таких языков, как C и C++. Для определенных типов приложений это может помочь вам повторно использовать библиотеки кода, написанные на этих языках.

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

Примеры приложений можно найти здесь.

Обычно вам необходимо:

  1. Установите Google Android NDK. Он содержит библиотеки, заголовки, примеры makfile и набор инструментов gcc
  2. Создайте исполняемый файл из кода C для ARM, оптимизируйте и при необходимости свяжите его с предоставленными библиотеками
  3. Подключитесь к телефону с помощью предоставленного интерфейса adb и протестируйте свой исполняемый файл.

Если вы хотите продать приложение:

  1. Создайте библиотеку из кода C
  2. Создайте простой код Java, который будет использовать эту библиотеку
  3. Встроить эту библиотеку в файл пакета приложения
  4. Протестируйте свое приложение
  5. Продавать или распространять бесплатно

Я не знаю, где его скачать, но я слышал, что вы можете получить копию NDK из репозитория Google Git в ветке пончиков.

Официальная позиция кажется такова, что это не то, чем вы когда-либо хотели бы заниматься. См. эту ветку в списке разработчиков Android. Google предполагает, что Android работает на различных устройствах (процессоры, дисплеи и т. д.). Таким образом, лучший способ обеспечить разработку — использовать (переносимый) управляемый код, ориентированный на виртуальную машину Dalvik. По этой причине Android SDK не поддерживает C/C++.

НО, взгляните на эту страницу:

Android включает набор библиотек C/C++, используемых различными компонентами системы Android. Эти возможности предоставляются разработчикам через платформу приложений Android.

Похоже, что платформа управляемых приложений находится поверх этих библиотек. Далее на странице перечислены библиотеки C/C++: стандартная библиотека C, мультимедиа, 3D, SQL lite и другие.

Поэтому все, что вам нужно, — это цепочка компиляторов, которая будет компилировать C/C++ для соответствующего ЦП (ARM, в случае G1). Несколько кратких инструкций о том, как это сделать, находятся здесь.

Чего я не знаю, так это где найти описания API, предоставляемых этими библиотеками. Я предполагаю, что где-то в SDK могут быть спрятаны заголовочные файлы, но документация может быть схематичной или отсутствовать. Но я думаю, что это можно сделать!

Надеюсь, это полезно. К сведению: я не писал нативных приложений для Android, а только несколько простых управляемых.

В последнее время я проводил много времени, беседуя с разработчиками Android. И я был удивлен, как мало разработчиков Android знают язык C. Большинство разработчиков используют только Java и убеждены, что C слишком сложен для их нужд. Но я попытаюсь разрушить этот миф: код на C может быть намного проще в написании и гораздо проще в исполнении.

Инструментарий

Первый шаг — набор инструментов. В этом уроке я буду использовать очень простой набор инструментов. Я уже скачал последнюю версию NDK (r21d) с официального сайта, добавил переменную среды ANDROID_NDK.

Для работы с конкретной платформой следует выбрать архитектуру процессора и целевой API.Например, aarch64-linux-android21 — это архитектура Android ARM64 с целевым API 21.

Привет, мир

Если вы не знакомы с C, я настоятельно рекомендую начать с книги Кернигана и Ритчи "Язык программирования C" (известной также как K&R C). Это очень просто, но все еще очень полезно в наше время. Как обычно, я начну с Привет, мир. Вот пример из этой книги (слегка модифицированный для современных ОС):

Хорошо, следующий шаг — сборка и запуск в качестве приложения командной строки на устройстве Android.

Я использую компилятор clang (это компилятор по умолчанию в NDK 14). Clang — это внешний компилятор для различных языков, включая C и C++, который использует LLVM в качестве внутреннего интерфейса. И небольшой шаг в теорию компиляции. В C есть 4 этапа компиляции:

  1. Предварительная обработка
  2. Фактическая компиляция
  3. Сборка
  4. Связь

Возвращаясь к практике, эта команда компилирует файл .c в объект, а затем связывает его с исполняемым файлом для платформы toolchain:

Если вы используете API 21 или более поздней версии, вам необходимо установить флаг для исполняемых файлов, не зависящих от позиции.

Начиная с Android 4.1 (уровень API 16) динамический компоновщик Android поддерживает позиционно-независимые исполняемые файлы (PIE). Начиная с Android 5.0 (уровень API 21) для исполняемых файлов требуется PIE. Чтобы использовать PIE для сборки исполняемых файлов, установите флаг -fPIE. Этот флаг усложняет использование ошибок повреждения памяти за счет случайного расположения кода. 1

Для запуска исполняемого файла helloworld требуется Android-устройство или эмулятор. Скопируйте исполняемый файл и запустите его через adb:

Поздравляем 🎉, вы только что запустили свое первое приложение командной строки C для Android. Этот подход отлично подходит для тестирования некоторых функций на C без необходимости создавать приложение для Android, компилировать Java, упаковывать файл .apk и т. д. Просто скопируйте двоичный файл и запустите — очень просто.

Библиотеки

В C есть 2 типа библиотек:

В этом разделе я создам исполняемый файл, связанный с библиотеками обоих типов. В качестве примера приложения я решил создать небольшую утилиту, которая сравнивает результаты двух реализаций обратного квадратного корня: системной математической библиотеки и хака, который использовался в Quake III. В статической библиотеке я реализовал версию обратного квадратного корня в Quake III, в динамической — версию math.h. И этот исполняемый файл запросит у пользователя ввод и распечатает оба результата.

Начнем со статической библиотеки. Опять же, небольшой шаг в теории:

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

Скомпилируйте этот хакерский файл .c в объект

Эта команда скомпилирует файл .c в файл .o (объект). Это промежуточный объект, который будет использоваться для создания статической библиотеки. Для более глубокого понимания того, что такое объекты, воспользуемся утилитой nm:

Команда nm может сообщить список символов в данной библиотеке. Он работает как со статическими, так и с разделяемыми библиотеками. Для данной библиотеки nm может перечислить определенные имена символов, значение каждого символа и тип символа. Он также может указать, где в исходном коде был определен символ (по имени файла и номеру строки), если эта информация доступна в библиотеке (см. параметр -l). Тип символа отображается в виде буквы; нижний регистр означает, что символ является локальным, а верхний регистр означает, что символ является глобальным (внешним). 3

Обычные типы символов включают:

  • T (обычное определение в разделе кода)
  • D (раздел инициализированных данных)
  • B (раздел неинициализированных данных)
  • U (не определено; символ используется библиотекой, но не определяется библиотекой)
  • W (слабо; если этот символ также определен в другой библиотеке, это определение имеет приоритет над этим).

Мы проверим все наши артефакты (объекты, библиотеки, исполняемые файлы) утилитой nm. Давайте проверим fast-inverse-square-root.o:

Как упоминалось выше, T означает определение символа (в нашем случае метода) внутри библиотеки. Следующий шаг: заархивировать объектный файл в файл .a

Программа gnu ar создает, модифицирует и извлекает из архивов. Архив — это отдельный файл, содержащий набор других файлов в структуре, позволяющей извлекать исходные отдельные файлы (называемые членами архива). 4

Вы должны получить файл libstatic.a. Вы можете проверить список символов в архиве так же, как мы делаем это для файлов .o.

Общая библиотека сложнее, начнем с определения:

Общие библиотеки — это библиотеки, загружаемые программами при их запуске.Если общая библиотека установлена ​​правильно, все программы, которые запускаются впоследствии, автоматически используют новую общую библиотеку. На самом деле это гораздо более гибкий и сложный подход, чем этот, потому что подход, используемый Linux, позволяет вам: обновлять библиотеки и по-прежнему поддерживать программы, которые хотят использовать более старые, несовместимые с предыдущими версиями этих библиотек; переопределять определенные библиотеки или даже определенные функции в библиотеке при выполнении конкретной программы; делать все это, пока программы работают с использованием существующих библиотек. 5

Поскольку Android API 23 NDK поддерживает dylib SONAME .

Каждая разделяемая библиотека имеет специальное имя, называемое soname. Soname имеет префикс lib , имя библиотеки, фразу .so, за которой следует точка и номер версии, который увеличивается при каждом изменении интерфейса (как специальное исключение, библиотеки C самого низкого уровня не начинаются с библиотека). Полное soname включает префикс каталога, в котором оно находится; в работающей системе полное имя soname — это просто символическая ссылка на реальное имя разделяемой библиотеки. Каждая разделяемая библиотека также имеет реальное имя, которое представляет собой имя файла, содержащего фактический код библиотеки. Настоящее имя добавляет к сонимению точку, второстепенный номер, еще одну точку и номер выпуска. Последний период и номер выпуска являются необязательными. Дополнительный номер и номер выпуска поддерживают управление конфигурацией, позволяя точно знать, какие версии библиотеки установлены. 6

Есть небольшая проблема с soname в Android: все платформы Android 23+ требуют soname , но только Android 23+ могут его прочитать. Вот почему, если ваш текущий минимальный API ниже 23, вы всегда должны устанавливать soname == realname. Версии soname пока нет 😔

Код обратного квадратного корня с использованием math.h:

Давайте создадим общую библиотеку:

Вы должны получить libdynamic.so. Проверим с помощью nm:

Есть 2 интересные строки:

  • T rsqrt — это метод, определенный в этой библиотеке
  • U sqrtf — система sqrtf, определенная в math.h

Теперь проверьте заголовок общей библиотеки. Для этого мы можем использовать утилиту readelf.

readelf отображает информацию об одном или нескольких объектных файлах формата ELF. 7

Самое большое преимущество использования ELF — это независимость от ЦП, ABI или операционной системы и возможность использования в любом месте для проверки любого объекта ELF. Если у вас предустановлены инструменты gcc, вы можете использовать sysytem readelf. Для пользователей macOS я могу порекомендовать brew install greadelf

Как видно из заголовка libdynamic.so, soname совпадает с именем файла и имеет две зависимости от системных библиотек: libdl и libc. Но также нам нужно связать здесь математическую библиотеку из-за неразрешенного символа sqrtf. Для этого просто добавьте флаг -lm

Следующий шаг — сборка исполняемого файла (helloworld.h):

Сначала попробуйте скомпилировать helloworld.c:

Линкер сказал, что нет Q_rsqrt и rsqrt. Попробуйте связать библиотеки:

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

Кроссплатформенная компиляция и CMake

C является кроссплатформенным языком, и в общем случае код C может быть скомпилирован для любой платформы. Заголовки, которые я импортировал в свой образец проекта, относятся к libc, это стандартная библиотека для языка программирования C, как указано в стандарте ANSI C. В этом разделе я покажу, как создать пример приложения для хост-системы (в моем случае macOS) и Android. Для этого я использую CMake:

CMake – это кроссплатформенное семейство инструментов с открытым исходным кодом, предназначенное для создания, тестирования и упаковки программного обеспечения. CMake используется для управления процессом компиляции программного обеспечения с помощью простых файлов конфигурации, независимых от платформы и компилятора, а также для создания собственных make-файлов и рабочих пространств, которые можно использовать в выбранной вами среде компилятора. 8

Android SDK в настоящее время содержит собственную версию CMake, мы будем использовать ее.

Все правила компиляции обычно описываются в CMakeList.txt. Вы можете проверить синтаксис конфигурации CMake здесь. Моя версия CMakeLists.txt для примера быстрого обратного квадратного корня:

Сборка CMake состоит из двух шагов: создание make-файлов для целевой платформы и запуск сборки

Скомпилируйте проект для Mac:

Для Android нам нужно передать файл android.toolchain.cmake с параметрами для CMake. А для Android скрипты будут выглядеть так:

Как видите, CMake — это очень простой инструмент для создания кроссплатформенного кода C.

Теперь вы можете попробовать что-то более сложное с одной из IDE, поддерживающих систему сборки CMake (например, JetBrains CLion).

Что дальше?

Согласно официальной документации, Google рекомендует использовать NDK по двум причинам:

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

С моей точки зрения, C можно использовать для любого конкретного кода в вашем проекте, за исключением части пользовательского интерфейса и связи с системой. Кроме того, это может быть полезно при кроссплатформенной разработке общей кодовой базы.

Надеюсь, мой урок убедил вас перестать бояться кода на C и вдохновил вас написать что-нибудь самостоятельно. Мой образец кроссплатформенной компиляции доступен на Github.

Читайте также: