2013-03-11 15 views
6

Wykonanie SWIG tutorial i użycie przykładów example.c, example.i, ponieważ zostały tam dostarczone. Wygenerowałem plik lisp z swig -cffi example.i.CL i SWIG: przykład pracy?

Ale kiedy uruchamiam test.lisp z SBCL, otrzymuję skargę dotyczącą niezdefiniowanej funkcji cudzoziemca, a także reklamacje podczas kompilowania samego example.lisp. Jestem prawie pewien, że muszę jeszcze skompilować mój plik example.c do biblioteki, a następnie jakoś powiedzieć SBCL, aby go załadował! Ale dokumenty są bardzo skąpe, z wyjątkiem this.

Czy ktoś może mi powiedzieć, jak to zrobić, czy jest lepszy sposób niż SWIG do automatycznego generowania powiązań CFFI ze źródeł C/C++?

wyjście 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) 

Odpowiedz

8

Po pierwsze, trzeba skompilować bibliotekę C. Zrobić coś takiego:

gcc -shared example.c -o libexample.so 

oczywiście, złożonego istniejącej kompilacji biblioteki mogłyby być znacznie bardziej skomplikowane - jeśli owijania istniejącej biblioteki, to prawdopodobnie pochodzi z pewnego rodzaju Makefile, które pomogą Ci zbudować.

Następnie, w Lisp, użyj CFFI do zdefiniowania i załadowania biblioteki. Wydaje się to być główną częścią, której brakuje.

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

Ta część:

(t (:default "libexample")) 

jest warunkowe, które można wykorzystać, aby dać różne instrukcje ładowania dla różnych platform. (t ...) to opcja catchall, podobnie jak w COND. Dokładną składnię można znaleźć w dokumentacji biblioteki define-foreign.

Powinieneś teraz normalnie używać cffi: defcfun i tak dalej, aby zdefiniować funkcje w bibliotece. To, co robi plik SWIG generowane dla ciebie, więc załadować go:

(load "example.lisp") 

Teraz można wywoływać funkcje jak normalnych funkcji Lisp:

(fact 5) 
    => 120 
+1

piękne. musiałem również ustawić LD_LIBRARY_PATH, aby można było znaleźć moją bibliotekę libexample.so. Możesz dodać to do swojej odpowiedzi. –