Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CL and SWIG: working example?

Doing a SWIG tutorial, and using the example.c, example.i as they provided there. I generated lisp file with swig -cffi example.i.

But when I run test.lisp with SBCL, i get a complaint about undefined alien function, as well as complaints when compiling the example.lisp itself. I'm pretty sure I still have to compile my example.c into a library and then somehow tell SBCL to load it! But the docs are very scant on this, except for this.

Can somebody tell me how to do this or is there a better way than SWIG to automatically generate CFFI bindings from C/C++ sources??

sbcl output:

...
; 
; 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)
like image 931
Robin B Avatar asked Mar 11 '13 19:03

Robin B


1 Answers

First, you need to compile the C library. Do something like:

gcc -shared example.c -o libexample.so

Of course, for a complex existing library compilation could be considerably more complex -- if you're wrapping an existing library, it probably comes with some sort of Makefile to help you build it.

Then, in Lisp, use CFFI to define and load the library. This seems to be the main part that you're missing.

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

This part:

(t (:default "libexample"))

is a conditional which you can use to give different loading instructions for different platforms. (t ...) is the catchall option, much like with COND. You can find the exact syntax in the documentation for define-foreign-library.

You would now normally use cffi:defcfun and so on to define the functions in the library. This is what the SWIG-generated file does for you, so load it:

(load "example.lisp")

You can now call the functions as normal Lisp functions:

(fact 5)
  => 120
like image 100
svk Avatar answered Nov 06 '22 06:11

svk