使用注释通过 gobject introspection 生成多语言绑定

转载时请注明出处和作者联系方式:http://blog.csdn.net/mimepp

作者联系方式:YU TAO <yut616 at sohu dot com>

关键字: gobject introspection, gir, typelib, python binding, javascript binding, g-ir-scanner, g-ir-compiler

这里记录一下使用注释的方式来生成多语言绑定,以便备查。

准备工作:

安装 gobject introspection

sudo apt-get install libgirepository1.0-dev

需要绑定的 C 代码:

网上比较常见的 foo.c, foo.h

foo.h

#ifndef FOO_H
#define FOO_H

void foo_hello (void);

#endif

foo.c

#include <stdio.h>
#include "foo.h"

/**
 * foo_hello:
 *
 * This function just for test.
 */
void
foo_hello (void)
{
        printf ("hello foo!\n");
}

留意 foo.c 中 foo_hello 的注释部分,此部分是需要符合 gtk-doc annotations 语法的,可以参考:

https://live.gnome.org/GObjectIntrospection/Annotations

编译库文件:

gcc -fPIC -shared foo.c -o libfoo.so.0

g-ir-scanner 生成 gir:

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 生成 typelib:

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
重新加载。

使用 gjs 来运行:

编写一个 test.js,如下:

const Foo=imports.gi.Foo;
Foo.hello();
运行结果如下:

$ gjs test.js 
hello foo!

使用 python 来运行:

编写一个test.py,如下:

from gi.repository import Foo
Foo.hello()

运行结果:

$ python test.py 
hello foo!


你可能感兴趣的:(语言,library,binding,Annotations,linker,portability)