...

воскресенье, 15 июня 2014 г.

Использование в языке 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 dev-libev




Для использования её в проекте на 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(C) 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(C). Фактически её вызов будет происходить из недр подключенной библиотеки, а она у нас написана на С. Следовательно, соглашение о вызове 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 в редакторе хабратопиков.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий