2013-03-11 58 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