使用SBCL FFI传递和接收字符串(Passing and receiving strings with SBCL FFI)

编程入门 行业动态 更新时间:2024-10-24 16:27:31
使用SBCL FFI传递和接收字符串(Passing and receiving strings with SBCL FFI)

我有一个用优化的c(library.c)编写的复杂库:

#include <stdio.h> #include "library.h" void make_fullname(char* fullname, char* name, int version) { sprintf(fullname, "%s-%d", name, version); printf("lib-name: %s\n", name); printf("lib-fullname: %s\n", fullname); }

其中library.h包含

void make_fullname(char* fullname, char* name, int version);

该库编译如下:

gcc library.c -o library.so -shared

我试图从SBCL中使用它,这是我的最后一个(我放弃并转向stackoverflow):

(load-shared-object "library.so") (define-alien-routine make_fullname void (fullname (c-string :external-format :ascii)) (name (c-string :external-format :ascii)) (x int)) (defun print-name-version (name version) (with-alien ((fullname (c-string :external-format :ascii))) (setf fullname (make-alien char 100)) (setf fullname "dummy-string") (make_fullname fullname name version) (format t "~a~%" fullname)))

在运行时,例如,(print-name-version“Program”1)我得到了这个

lib-name: Program lib-fullname: Program-1 dummy-string NIL

所以,除了将字符串传递回lisp之外,一切都有效。 这个例子中有什么不妥之处? 谢谢,安德烈。

更新我已经让我的lisp代码工作,但我仍然不明白为什么原始代码段失败。 这是一个有效的工作:

(defun print-name-version (name version) (let ((fullname (make-alien char 100))) (make_fullname fullname name version) (with-alien ((fn-str-repr (c-string :external-format :ascii) fullname)) (format t "~a~%" fn-str-repr)) (free-alien fullname)))

I have a sophisticated library written in optimized c (library.c):

#include <stdio.h> #include "library.h" void make_fullname(char* fullname, char* name, int version) { sprintf(fullname, "%s-%d", name, version); printf("lib-name: %s\n", name); printf("lib-fullname: %s\n", fullname); }

where library.h contains

void make_fullname(char* fullname, char* name, int version);

The library is compiled as follows:

gcc library.c -o library.so -shared

I am trying to make use of it from SBCL, here is my final take (the one on which I give up and turn to stackoverflow):

(load-shared-object "library.so") (define-alien-routine make_fullname void (fullname (c-string :external-format :ascii)) (name (c-string :external-format :ascii)) (x int)) (defun print-name-version (name version) (with-alien ((fullname (c-string :external-format :ascii))) (setf fullname (make-alien char 100)) (setf fullname "dummy-string") (make_fullname fullname name version) (format t "~a~%" fullname)))

Upon running, e.g., (print-name-version "Program" 1) I get this

lib-name: Program lib-fullname: Program-1 dummy-string NIL

So, everything works except for passing the string back into lisp. What is amiss in this example? Thanks, Andrei.

Update I have got my lisp code to work, but I still don't really get why the original snippet fails. Here is a working one:

(defun print-name-version (name version) (let ((fullname (make-alien char 100))) (make_fullname fullname name version) (with-alien ((fn-str-repr (c-string :external-format :ascii) fullname)) (format t "~a~%" fn-str-repr)) (free-alien fullname)))

最满意答案

我从未使用过SBCL原生FFI绑定,但我想我已经弄明白了。 为了将来参考,您将更有可能获得有关CFFI的帮助,而不是实现特定的FFI绑定。

当从Lisp代码访问时,外来类型c-string的变量自动转换为Lisp字符串。 顶级函数make_fullname是Lisp代码,它make_fullname调用外部例程,但到那时fullname已经转换为Lisp字符串,然后转换为新的 c字符串,一旦调用完成就会被丢弃。

您需要执行在编辑中执行的操作:分配存储缓冲区并将其传递给alien函数,并将关联的c-string变量视为该存储上的Lisp视图。

I have never used SBCL native FFI bindings, but I think I figured it out. For future reference, you would be more likely to get help about CFFI rather than implementation specific FFI bindings.

Variables of alien type c-string are automatically converted to Lisp strings when accessed from Lisp code. The top level function make_fullname is Lisp code, which in turns calls the alien routine, but by that time fullname has been converted to a Lisp string, which then gets converted to a new c-string, which is discarded once the call finishes.

You need to do what you did in the edit: allocate storage buffer and pass that to the alien function, and treat the associated c-string variable as a Lisp view on that storage.

更多推荐

本文发布于:2023-08-03 14:27:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1390172.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:字符串   FFI   SBCL   strings   receiving

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!