【问题标题】:How to use FFI:def-call-in in clisp如何在 clisp 中使用 FFI:def-call-in
【发布时间】:2015-05-26 08:15:42
【问题描述】:

我已经知道如何使用 FFI:def-call-out 将 C 代码创建的共享对象用于 Clisp,但我不知道如何使用 FFI:Def-call-in

我不知道这个过程,实际上我很困惑 clisp 是否还会创建一些 C 函数可以使用的 .so 文件或其他文件。

有人可以解释一个编写此类回调函数的最小工作示例吗?

【问题讨论】:

    标签: lisp common-lisp ffi clisp


    【解决方案1】:

    Example 32.7. Calling Lisp from C:

    要使用 Lisp 函数 SORT 而不是 C 库函数 qsort 对双浮点数组进行排序,可以使用以下接口代码 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
    

    link.sh 中添加sort1.oNEW_LIBSNEW_FILES。创建一个包含表单的文件package.lisp

    (MAKE-PACKAGE "FFI-TEST" :use '(“COMMON-LISP” “FFI”))
    

    并在link.sh 中将package.lisp 添加到TO_PRELOAD。继续:

    $ 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
    

    【讨论】:

    • 这里的 base/lisp.run 和 listinit.mem 是什么...我找到了这个例子,但在这里我卡住了。
    • 这些是 clisp 运行时和内存映像文件; clisp --help 将在第二行打印他们的位置。
    猜你喜欢
    • 1970-01-01
    • 2020-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多