6

做一个SWIG 教程,并使用他们在那里提供的 example.c、example.i。我生成了 lisp 文件swig -cffi example.i

但是当我test.lisp使用 SBCL 运行时,我收到关于未定义外星函数的投诉,以及编译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"
...

测试.lisp

;call C functions defined in example.c

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

1 回答 1

9

首先,您需要编译 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
于 2013-03-11T20:08:15.610 回答