2015-05-26 97 views
1

我已經想出瞭如何使用從C代碼創建的共享對象到Clisp中,使用FFI:def-call-out,但我無法弄清楚如何使用FFI:Def-call-in如何使用FFI:def-call in in clisp

我不知道這個過程,實際上我很困惑,如果clisp也會創建一些.so文件,說明一些C函數可以使用或者其他的東西。

有人可以請解釋一個寫這種回調函數的最小工作示例嗎?

回答

1

Example 32.7. Calling Lisp from C

排序使用Lisp函數SORT代替C庫函數qsort雙float數組,可以使用下面的接口代碼sort1.c。主要的問題是傳遞一個可變大小的數組。

extern void lispsort_begin (int); 
void* lispsort_function; 
void lispsort_double (int n, double * array) { 
    double * sorted_array; 
    int i; 
    lispsort_begin(n); /* store #'sort2 in lispsort_function */ 
    sorted_array = ((double * (*) (double *)) lispsort_function) (array); 
    for (i = 0; i < n; i++) array[i] = sorted_array[i]; 
    free(sorted_array); 
} 

這是伴隨着sort2.lisp

(DEFPACKAGE "FFI-TEST" (:use 「COMMON-LISP」 「FFI」)) 
(IN-PACKAGE "FFI-TEST") 
(EVAL-WHEN (compile) (setq FFI:*OUTPUT-C-FUNCTIONS* t)) 
(FFI:DEF-CALL-IN lispsort_begin (:ARGUMENTS (n int)) 
    (:RETURN-TYPE nil) 
    (:LANGUAGE :stdc)) 
(FFI:DEF-C-VAR lispsort_function (:type c-pointer)) 
(defun lispsort_begin (n) 
    (setf (cast lispsort_function 
       `(c-function 
       (:ARGUMENTS (v (c-ptr (c-array double-float ,n)))) 
       (:RETURN-TYPE (c-ptr (c-array double-float ,n)) 
           :malloc-free))) 
     #'sort2)) 
(defun sort2 (v) 
    (declare (type vector v)) 
    (sort v #'<)) 

要進行測試,使用下面的測試文件sorttest.lisp

(EVAL-WHEN (compile) (setq FFI:*OUTPUT-C-FUNCTIONS* t)) 
(FFI:DEF-CALL-OUT sort10 
    (:name "lispsort_double") 
    (:LANGUAGE :stdc) 
    (:ARGUMENTS (n int) 
       (array (c-ptr (c-array double-float 10)) :in-out))) 

現在嘗試

$ clisp-link create sort sort2.c sorttest.c 
$ cc -O -c sort1.c 
$ cd sort 
$ ln -s ../sort1.o sort1.o 

sort1.o加到NEW_LIBSNEW_FILES in link.sh。創建一個文件package.lisp包含表單

(MAKE-PACKAGE "FFI-TEST" :use '(「COMMON-LISP」 「FFI」)) 

link.sh添加package.lispTO_PRELOAD。 Proceedings:

$ cd .. 
$ base/lisp.run -M base/lispinit.mem -c sort2.lisp sorttest.lisp 
$ clisp-link add base base+sort sort 
$ base+sort/lisp.run -M base+sort/lispinit.mem -i sort2 sorttest 
> (sort10 10 '#(0.501d0 0.528d0 0.615d0 0.550d0 0.711d0 
       0.523d0 0.585d0 0.670d0 0.271d0 0.063d0)) 
#(0.063d0 0.271d0 0.501d0 0.523d0 0.528d0 0.55d0 0.585d0 0.615d0 0.67d0 0.711d0) 
$ rm -r base+sort 
+0

什麼是基地/ lisp.run和listinit.mem在這裏...我發現這個例子,但在這裏我卡住了。 – Rorschach

+0

這些是clisp運行時和內存映像文件; 'clisp --help'將在第二行打印它們的位置。 – sds

+0

是剛剛在磁盤上搜索它..感謝您的幫助。 – Rorschach