如何在 cffi 中将 NULL 作为 :string 发送

发布于 2025-01-12 22:41:47 字数 1254 浏览 0 评论 0原文

我正在尝试从 lisp 端使用 wayland-client,这是我的代码:

(define-foreign-library wayland-client
  (:unix (:or "libwayland-client.so.0.20.0" "libwayland-client.so"))
  (t (:default "libwayland-client")))


(use-foreign-library wayland-client)

(defcfun "wl_display_connect" :pointer
  (name :string))

(wl-display-connect (null-pointer));;return NULL

C 语言代码,来自 here

#include <stdio.h>
#include <stdlib.h>
#include <wayland-client.h>

struct wl_display *display = NULL;

int main(int argc, char **argv) {

    display = wl_display_connect(NULL);
    if (display == NULL) {
    fprintf(stderr, "Can't connect to display\n");
    exit(1);
    }
    printf("connected to display\n");

    wl_display_disconnect(display);
    printf("disconnected from display\n");    
    exit(0);
}

我已经测试了 C 版本并且它有效,那么 lisp 版本应该如何正确?

如何在此处定义wl_display_connect

struct wl_display* wl_display_connect(const char *name)

I'm trying to use wayland-client from lisp side, this is my code:

(define-foreign-library wayland-client
  (:unix (:or "libwayland-client.so.0.20.0" "libwayland-client.so"))
  (t (:default "libwayland-client")))


(use-foreign-library wayland-client)

(defcfun "wl_display_connect" :pointer
  (name :string))

(wl-display-connect (null-pointer));;return NULL

Code in C, come from here

#include <stdio.h>
#include <stdlib.h>
#include <wayland-client.h>

struct wl_display *display = NULL;

int main(int argc, char **argv) {

    display = wl_display_connect(NULL);
    if (display == NULL) {
    fprintf(stderr, "Can't connect to display\n");
    exit(1);
    }
    printf("connected to display\n");

    wl_display_disconnect(display);
    printf("disconnected from display\n");    
    exit(0);
}

I have test the C one and it worked, how should the lisp one be correct?

How wl_display_connect been defined from here

struct wl_display* wl_display_connect(const char *name)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

给我一枪 2025-01-19 22:41:48

我不是 CFFI 方面的专家,但我认为诀窍是说事情是 (:pointer :char) 而不是 :string 。给定这个简单的 C 函数:

#include <stdio.h>

char *ts(char *x) {
  if (x == NULL) {
    printf("Got a null\n");
  }
  return x;
}

以及这个 CFFI 声明:

(defcfun (ts "ts")
    (:pointer :char)
  (name (:pointer :char)))

那么这将起作用:

> (null-pointer-p (ts (null-pointer)))
Got a null
t

然后您可以使用外部字符串调用它,但您需要处理它们的分配和取消分配: (ts "foo")行不通的。但这将:

(defun ts-wrapper (s)
  (with-foreign-string (x s)
    (foreign-string-to-lisp (ts x))))

现在:

> (ts-wrapper "foo")
"foo"
3

显然在您的情况下,您不需要处理从外部字符串的转换。

I am not an expert on CFFI but I think the trick is to say that things are (:pointer :char)s not :strings. Given this trivial C function:

#include <stdio.h>

char *ts(char *x) {
  if (x == NULL) {
    printf("Got a null\n");
  }
  return x;
}

And this CFFI declaration:

(defcfun (ts "ts")
    (:pointer :char)
  (name (:pointer :char)))

Then this will work:

> (null-pointer-p (ts (null-pointer)))
Got a null
t

And you can then call it with foreign strings, but you need to deal with allocating and deallocating them: (ts "foo") won't work. But this will:

(defun ts-wrapper (s)
  (with-foreign-string (x s)
    (foreign-string-to-lisp (ts x))))

And now:

> (ts-wrapper "foo")
"foo"
3

Obviously in your case you don't need to deal with the conversion back from the foreign string.

抠脚大汉 2025-01-19 22:41:48

您可以使用 (cffi:null-pointer) 因为 string 是指向 char 数组的指针。

You can use (cffi:null-pointer) since string is a pointer to char array.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文