在 Common Lisp 中使用 CFFI,调用返回指针的函数
Using CFFI in Common Lisp, calling functions returning pointers
我正在使用 SBCL,并尝试使用 CFFI。我开始按照手册 here 进行操作,但我一直发现函数 curl_easy_init
未定义,所以我决定尝试一个更简单的案例。
一些功能按预期工作,而其他功能似乎未定义。解释如下:
这是我的 C 代码:
#include <stdio.h>
#include <stdlib.h>
/* "Works" except output doesn't appear. Not important for now */
void hello()
{
printf("Hello World\n");
}
/* Works as expected */
float add(float x1, float x2)
{
return x1 + x2;
}
/* appears to not be defined in SBCL*/
void* init_this()
{
return malloc(10);
}
/* Appears to not be defined in SBCL*/
void clean_this(void* ptr)
{
free(ptr);
}
此 C 文件编译为:
gcc -shared -o cffi_test.so -fPIC cffi_test.c
我的 Common Lisp 代码:
(quicklisp:quickload "cffi")
(defpackage :my-cffi
(:use :common-lisp :cffi))
(in-package :my-cffi)
(export '(hello add init_this clean_this))
(define-foreign-library cffi_test
(t (:default "~/Work/clisp/cffi_test")))
(use-foreign-library cffi_test)
(defcfun "hello" :void)
(defcfun "add" :float (x1 :float ) (x2 :float))
(defcfun "init_this" :pointer)
(defcfun "clean_this" :void (handle :pointer))
如我所料得到的:
* (my-cffi:add 3.0 4.0)
7.0
似乎有问题:
(my-cffi:init_this)
产生错误:
The function MY-CFFI:INIT_THIS is undefined.
[Condition of type UNDEFINED-FUNCTION]
...
Backtrace:
0: (SB-IMPL::RETRY-%COERCE-NAME-TO-FUN MY-CFFI:INIT_THIS NIL)
Locals:
SB-IMPL::NAME = MY-CFFI:INIT_THIS
SB-IMPL::STRICTLY-FUNCTIONP = NIL
我在 clean_this
中遇到了同样的错误,在上面的 link 中,按照手册,curl_easy_init
启发了这个实验。
作为字符串提供给 CFFI:DEFCFUN
的外国名称将使用通用函数 CFFI:TRANSLATE-NAME-FROM-FOREIGN
转换为 lispier 名称。默认行为是将下划线更改为连字符:
CL-USER> (cffi:translate-name-from-foreign "mylib_fun_name" *package*)
MYLIB-FUN-NAME
您也可以在函数定义中明确给出一个 lisp 名称:
(defcfun ("mylib_fun_name" fun-name) ...)
我正在使用 SBCL,并尝试使用 CFFI。我开始按照手册 here 进行操作,但我一直发现函数 curl_easy_init
未定义,所以我决定尝试一个更简单的案例。
一些功能按预期工作,而其他功能似乎未定义。解释如下:
这是我的 C 代码:
#include <stdio.h>
#include <stdlib.h>
/* "Works" except output doesn't appear. Not important for now */
void hello()
{
printf("Hello World\n");
}
/* Works as expected */
float add(float x1, float x2)
{
return x1 + x2;
}
/* appears to not be defined in SBCL*/
void* init_this()
{
return malloc(10);
}
/* Appears to not be defined in SBCL*/
void clean_this(void* ptr)
{
free(ptr);
}
此 C 文件编译为:
gcc -shared -o cffi_test.so -fPIC cffi_test.c
我的 Common Lisp 代码:
(quicklisp:quickload "cffi")
(defpackage :my-cffi
(:use :common-lisp :cffi))
(in-package :my-cffi)
(export '(hello add init_this clean_this))
(define-foreign-library cffi_test
(t (:default "~/Work/clisp/cffi_test")))
(use-foreign-library cffi_test)
(defcfun "hello" :void)
(defcfun "add" :float (x1 :float ) (x2 :float))
(defcfun "init_this" :pointer)
(defcfun "clean_this" :void (handle :pointer))
如我所料得到的:
* (my-cffi:add 3.0 4.0)
7.0
似乎有问题:
(my-cffi:init_this)
产生错误:
The function MY-CFFI:INIT_THIS is undefined.
[Condition of type UNDEFINED-FUNCTION]
...
Backtrace:
0: (SB-IMPL::RETRY-%COERCE-NAME-TO-FUN MY-CFFI:INIT_THIS NIL)
Locals:
SB-IMPL::NAME = MY-CFFI:INIT_THIS
SB-IMPL::STRICTLY-FUNCTIONP = NIL
我在 clean_this
中遇到了同样的错误,在上面的 link 中,按照手册,curl_easy_init
启发了这个实验。
作为字符串提供给 CFFI:DEFCFUN
的外国名称将使用通用函数 CFFI:TRANSLATE-NAME-FROM-FOREIGN
转换为 lispier 名称。默认行为是将下划线更改为连字符:
CL-USER> (cffi:translate-name-from-foreign "mylib_fun_name" *package*)
MYLIB-FUN-NAME
您也可以在函数定义中明确给出一个 lisp 名称:
(defcfun ("mylib_fun_name" fun-name) ...)