GObject based libraries can be called - thanks GObject introspection - quite easy from
javascript (as well as e.g. python).
As vala builds on gobject, all code generated by vala can be introspected - when compiled with a fine selection of compiler switches.
Let's pretend that we have
got a small library written in vala and want to use it from gjs - maybe because the that library is wrapping another non-gobject library or doing some heavy calculations.
To build a introspectable library a good practice is, to just use
valac to generate the appropriate c-code and handle the build manually - or by using some build system.
When invoking
valac it is important
to pass the two both of switches
--library and
--gir. It is also important to specify the GIR name (
--gir) in the format
NAME-VERSION.gir whereas the library (
--library) name expects just
NAME-VERSION.
Build
Up to now it's just theory. The following lines guide you trough this process, step by step (testShared.vala is taken from
here):
$ ls
testShared.vala
$ valac --ccode --header=testShared.h \
--gir=TestShared-0.1.gir \
--library=TestShared-0.1 \
--pkg=gio-2.0 testShared.vala
$ ls
TestShared-0.1.gir TestShared-0.1.vapi
testShared.c testShared.h
testShared.vala
$ gcc -fPIC -shared -o libTestShared.so \
$(pkg-config --libs --cflags gobject-2.0) \
testShared.c
$ ls *.so
libTestShared.so
Typelib
After building the library we finally need to build the introspection data using
g-ir-compiler (part of gobject-introspection-devel):
$ g-ir-compiler --shared-library=libTestShared.so \
--output=TestShared-0.1.typelib TestShared-0.1.gir
$ ls *.gir *.typelib
TestShared-0.1.gir
TestShared-0.1.typelib
Testing
To finally test our introspectable data, why use
gjs.
We import the library using the (
gjs specific) "imports.gi" keyword:
const TestShared = imports.gi.TestShared;
print('Square of 42: ' + TestShared.square (42));
On the commandline it looks like this:
$ GI_TYPELIB_PATH=. LD_LIBRARY_PATH=. \
gjs --command="const TestShared = imports.gi.TestShared; \
print('Square of 42: ' + TestShared.square (42));"
** (gjs:12175): DEBUG: Command line: gjs
** (gjs:12175): DEBUG: Creating new context to eval console script
Square of 42: 1764
$
Done. We managed to call a library function from
gjs using GObject introspection. The creation of the (important) typelib should be included in you favorite build tools, one example using cmake can be found (again)
here.
Oone final reminder: Not just vala code can be imported, but all gobject based libraries (e.g. libgtop2 for system informations, clutter for fancy UIs and more)
Is there something I forgot? Tell me :)
❧