CL和SWIG:工作实例?

时间:2013-03-11 19:46:18

标签: common-lisp swig sbcl

执行SWIG tutorial,然后使用example.c,example.i。我使用swig -cffi example.i生成了lisp文件。

但是当我用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)

1 个答案:

答案 0 :(得分: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 ...)是catchall选项,就像COND一样。您可以在define-foreign-library的文档中找到确切的语法。

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

(load "example.lisp")

现在可以将函数称为普通的Lisp函数:

(fact 5)
  => 120