执行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)
答案 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