📜 ⬆️ ⬇️

Using third-party libraries in D

On the wave of interest in the language D, I decided to contribute to its popularization. The article is not for beginners, but more for those who consider D as a second language. It is known that at the dawn of its development, programming languages ​​have a poor set of libraries and this often prevents you from starting to write something serious on them. I hope the article will help someone to cross this barrier.
The features of the dub utility will be discussed below, as well as the connection of third-party packages and libraries written in C / C ++ using the example of the excellent libev library.

Dub utility


Honestly, I still “float” in the dmd options needed to compile and build the application. This is due to the dub utility, which takes care of all these concerns and allows you to postpone the study of compiling and building the application for later, when it really becomes necessary. In addition, this useful program performs the functions of a package manager, possessing functionality similar to the pip utilities for python, npm for javascript, etc.

Project Initialization


To initialize the application using the dub utility, you need to create a project directory, go to it and execute the command:
$ dub init 

As a result, the file dub.json will be created, with the help of which the configuration and parameters of the application build will be set. Also, the source subdirectory containing the app.d file with a plain heworld.
The application is built and / or launched by the same utility launched from the project root directory, that is, from the directory containing the dub.json file. To compile, build and run heloworld from the app.d file, just run the dub command.

Connection of third-party packages (libraries)


In terms of language, third-party D-libraries distributed as source codes are called packages. The dub utility uses the package registry at the following address . The use of libraries written with C / C ++ is also possible, but this requires the inclusion of special packages in the project, called binding . The library itself must be installed in the system. For example, libev , which will continue to be used, is installed on debian-like linux distributions as follows:
 $ sudo apt-get install libev-dev 

To use it in a project on D, you need a binding that a good person has already done and placed in the above named registry. There is also an instruction on what changes need to be made to the dub.json file in dub.json to use libev in the project. It all comes down to adding to the dependencies section of the dub.json file the dub.json name, version and, if necessary, some other parameters.
The next time you run the dub command, all the packages listed in dependencies will be checked and loaded if they are absent.
')

Heloworld using libev


After the above manipulations, the project is ready to use libev from libev . Below is the code that should be placed in the app.d file, and if everything went smoothly, we will get an executable file that will delight every second with the message “Hello, World!” In the console.

 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); } 

What is worth noting in terms of using third-party libraries in D programs?
First, the second line connects the package-binding to libev . Secondly, the callback function cb_timer defined as extern(C) . In fact, its call will come from the depths of the connected library, and we have it written in C. Consequently, the cb_timer calling cb_timer must correspond to the call of functions written in C.

What can I say in general, looking at the code? Apart from the features of the D language, which allowed defining the cb_timer in the body of the main function, the code differs little from the similar C program. This is due to the fact that the binding packages usually contain minimal binding on function calls from the ssh library. Often, for convenience, another level of binding is made that provides more readable code using the “syntactic sugar” of the D language. For example, similar code could look something like this.

 import std.stdio; import mercury.core; void main() { new TimerWatcher(1.0, 1.0, (revents) { writeln("Hello, World!"); }).start(); defaultEventLoop.start(); } 

By the way, the code above is real. I tried to make a high-level wrapper over libev using a parameterized class for watchers. It turned out like not bad. If this is interesting to someone - in the next article I will tell about it.

Upd: There is a good article on using the dub , the author described in some detail the main features of the utility.

PS: It would be nice to have already highlighted the syntax highlighting D in the habratopic editor.

Source: https://habr.com/ru/post/226301/


All Articles