关键字: gobject introspection, gir, typelib, python binding, javascript binding, g-ir-scanner, g-ir-compiler
这里记录一下使用注释的方式来生成多语言绑定,以便备查。
安装 gobject introspection
sudo apt-get install libgirepository1.0-dev
网上比较常见的 foo.c, foo.h
foo.h
#ifndef FOO_H #define FOO_H void foo_hello (void); #endif
#include <stdio.h> #include "foo.h" /** * foo_hello: * * This function just for test. */ void foo_hello (void) { printf ("hello foo!\n"); }
https://live.gnome.org/GObjectIntrospection/Annotations
gcc -fPIC -shared foo.c -o libfoo.so.0
g-ir-scanner --namespace=Foo --nsversion=1.0 --library=libfoo.la foo.h foo.c -o Foo-1.0.gir输出信息:
$ g-ir-scanner --namespace=Foo --nsversion=1.0 --library=libfoo.la foo.h foo.c -o Foo-1.0.gir Must specify package names on the command line g-ir-scanner: compile: gcc -Wall -pthread -I/usr/include/glib-2.0 -I/usr/lib/i386-linux-gnu/glib-2.0/include -c -o /work/test/tmp-introspect6jSTu2/Foo-1.0.o /work/test/tmp-introspect6jSTu2/Foo-1.0.c g-ir-scanner: link: libtool --mode=link --tag=CC gcc -o /work/test/tmp-introspect6jSTu2/Foo-1.0 -export-dynamic /work/test/tmp-introspect6jSTu2/Foo-1.0.o -L. libfoo.la -pthread -Wl,--export-dynamic -lgio-2.0 -lgobject-2.0 -lgthread-2.0 -lgmodule-2.0 -lrt -lglib-2.0 libtool: link: gcc -o /work/test/tmp-introspect6jSTu2/.libs/Foo-1.0 /work/test/tmp-introspect6jSTu2/Foo-1.0.o -pthread -Wl,--export-dynamic -Wl,--export-dynamic -L. ./libfoo.so -lgio-2.0 -lgobject-2.0 -lgthread-2.0 -lgmodule-2.0 -lrt -lglib-2.0 -pthread需要注意的是 g-ir-scanner 的参数 "--library=libfoo.la" 是需要使用 libfoo.la 的,如果是使用 “--library=foo” 会出现错误:
ERROR: can't resolve libraries to shared libraries: foo错误原因待查。
一个典型的 libfoo.la 的例子为:
# libfoo.la - a libtool library file # Generated by libtool (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1 # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='libfoo.so.0' # Names of this library. library_names='libfoo.so.0.0.0 libfoo.so.0 libfoo.so' # The name of the static archive. old_library='libfoo.a' # Linker flags that can not go in dependency_libs. inherited_linker_flags='' # Libraries that this one depends upon. dependency_libs='' # Names of additional weak libraries provided by this library weak_library_names='' # Version information for libfoo. current=0 age=0 revision=0 # Is this an already installed library? installed=no # Should we warn about portability when linking against -modules? shouldnotlink=no # Files to dlopen/dlpreopen dlopen='' dlpreopen='' # Directory that this library needs to be installed in: libdir='/usr/local/lib'这个文件你可以从随便一个 open source 里编译出来的 *.la 来获得。
当然上面的编译和生成 gir,你可以使用 automake/autoconf 来生成 libfoo.la 会更方便。
g-ir-compiler --includedir=. -o Foo-1.0.typelib Foo-1.0.gir
sudo cp Foo-1.0.gir /usr/share/gir-1.0/ sudo cp Foo-1.0.typelib /usr/lib/girepository-1.0/
sudo vi /etc/ld.so.conf在其中增加你的 libfoo.so 的路径,如 /work/test
sudo ldconfig重新加载。
编写一个 test.js,如下:
const Foo=imports.gi.Foo; Foo.hello();运行结果如下:
$ gjs test.js hello foo!
编写一个test.py,如下:
from gi.repository import Foo Foo.hello()
$ python test.py hello foo!