Использование в языке D сторонних библиотек

На волне интереса к языку D решил и я внести свой вклад в его популяризацию. Статья не для новичков, а больше для тех кто рассматривает D как второй язык. Известно, что на заре своего развития, языки программирования имеют небогатый набор библиотек и это часто не позволяет начинать писать на них что-то серьёзное. Надеюсь статья поможет кому-нибудь переступить этот барьер.Ниже будут рассмотрены возможности утилиты dub, а так же подключение сторонних пакетов и библиотек написанных на C/C++ на примере замечательной библиотеки libev.Утилита dubЧестно говоря, я до сих пор «плаваю» в опциях dmd, необходимых для компиляции и сборки приложения. Виной тому утилита dub, которая берет на себя все эти заботы и позволяет отложить изучение нюансов компиляции и сборки приложения на потом, когда это действительно станет необходимо. Кроме этого, эта полезная программка выполняет функции пакетного менеджера, обладая функционалом, аналогичным утилитам pip для python, npm для javascript и т.п.Инициализация проекта Для инициализации приложения с помощью утилиты dub надо создать каталог проекта, перейти в него и выполнить команду: $ dub init В результате будет создан файл dub.json, с помощью которого задается конфигурация и параметры сборки приложения. А также, подкаталог source, содержащий файл app.d с незамысловатым хелоуворлдом.Сборка и/или запуск приложения производится этой же утилитой, запускаемой из корневого каталога проекта, то есть из каталога, содержащего файл dub.json. Чтобы скомпилировать, собрать и запустить хелоуворлд из файла app.d, достаточно выполнить команду dub.Подключение сторонних пакетов (библиотек) В терминах языка, библиотеки сторонних разработчиков на D, распространяемые в виде исходных кодов, называются пакеты. Утилита dub использует реестр пакетов, находящийся по следующему адресу. Использование библиотек, написанных с помощью C/C++ также возможно, но для этого необходимо подключение в проект специальных пакетов, называемых binding. Сама же библиотека должна быть установлена в системе. Например, libev, которая дальше будет задействована, устанавливается в debian подобных дистрибутивах linux следующим образом: $ sudo apt-get install libev-dev Для использования её в проекте на D нужен биндинг, который добрый человек уже сделал и разместил в выше названном реестре. Там же есть инструкция, какие изменения нужно внести в файл dub.json для использования libev в проекте. Все сводится к добавлению в раздел dependencies файла dub.json имени пакета, версии и, по необходимости, некоторых других параметров.При следующем выполнении команды dub, все перечисленные в dependencies пакеты будут проверены и подгружены в случае их отсутствия.Хелоуворлд с использованием libev После выше описанных манипуляций проект готов к использованию фичей из libev. Ниже приведен код, который следует поместить в файл app.d, и если все прошло гладко, получим исполняемый файл, который будет радовать раз в секунду сообщением «Hello, World!» в консоле. import std.stdio; import deimos.ev;

void main () { ev_timer watcher; extern© void cb_timer (ev_loop_t* loop, ev_timer* watcher, int revents) { writeln («Hello, World!»); }

auto p_loop = ev_loop_new (EVFLAG_AUTO); ev_timer_init (&watcher, &cb_timer, 1.0, 1.0); ev_timer_start (p_loop, &watcher); ev_run (p_loop, 0); } Что тут стоит отметить в плане использования сторонних библиотек в программах на D? Во-первых, во второй строке подключается пакет-биндинг к libev. Во-вторых, функция обратного вызова cb_timer определена как extern©. Фактически её вызов будет происходить из недр подключенной библиотеки, а она у нас написана на С. Следовательно, соглашение о вызове cb_timer должно соответствовать вызову функций написанных на С.Что можно сказать в целом, глядя на код? Не считая фичи языка D, позволившей определить cb_timer в теле функции main, код мало отличается от аналогичной программы на C. Это связано с тем, что пакеты-биндинги обычно содержат минимальную обвязку над вызовами функций из сишных библиотек. Часто для удобства делается еще один уровень обвязки, который предоставляет более читаемый код с использованием «синтаксического сахара» языка D. Например, аналогичный код мог бы выглядеть как-то так.

import std.stdio; import hilevel.libev;

void main () { auto watcher = new TimerWatcher (1.0, 1.0, (revents) { writeln («Hello, World!»); }); defaultEventLoop.start (); } Кстати, код приведенный выше — реально существующий. Я попробовал сделать высокоуровневую обертку над libev, используя параметризованный класс для вотчеров. Получилось вроде неплохо. Если это будет кому-то интересно — в следующей статье расскажу об этом.PS: Неплохо бы было уже сделать подсветку синтаксиса D в редакторе хабратопиков.

© Habrahabr.ru