2013-03-11 87 views
6

做一个SWIG tutorial,并使用它们提供的example.c,example.i。我生成了与swig -cffi example.i lisp文件。CL和SWIG:工作示例?

但是当我用SBCL运行test.lisp时,我收到了关于未定义外来函数的投诉,以及编译example.lisp本身时的投诉。我很确定我仍然需要将我的example.c编译成一个库,然后以某种方式告诉SBCL加载它!但是这个文档非常少,除了this

有人可以告诉我该怎么做,或者有没有比SWIG更好的方式从C/C++源自动生成CFFI绑定?

SBCL输出:

... 
; 
; caught STYLE-WARNING: 
; Undefined alien: "fact" 
; 
; compilation unit finished 
; caught 1 STYLE-WARNING condition 
; 
; caught STYLE-WARNING: 
; Undefined alien: "my_mod" 
... 

test.lisp

;call C functions defined in example.c 

(require :cffi) 
;;;(require :example "example.lisp") 
(load "example.lisp") 
(fact 2) 
(quit) 

回答

8

首先,你需要编译的C库。这样做:

gcc -shared example.c -o libexample.so 

当然,对于一个复杂的现有库的编译可能会复杂得多 - 如果你包装现有库,它可能带有某种Makefile文件来帮助你建立它。

然后,在Lisp中,使用CFFI来定义和加载库。这似乎是你错过的主要部分。

(cffi:define-foreign-library libexample 
    (t (:default "libexample"))) ;; note no .so suffix here 
(cffi:use-foreign-library libexample) 

这一部分:

(t (:default "libexample")) 

是有条件的,你可以用它来给不同平台加载指令。 (t ...)是一个选择,很像COND。你可以在define-foreign-library的文档中找到确切的语法。

您现在通常会使用cffi:defcfun等来定义库中的函数。这就是SWIG生成的文件不适合你,所以加载:

(load "example.lisp") 

现在,您可以调用作为普通Lisp的功能:

(fact 5) 
    => 120 
+1

美丽。还必须设置LD_LIBRARY_PATH,以便可以找到我的libexample.so。你可能想把这个添加到你的答案中。 – 2013-03-11 20:17:17