You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在CFFI中向:string类型参数传递NULL?Wayland-Client库的Lisp调用适配方案

Fixing wl_display_connect Returning NULL in CFFI Code

Let's break down why your current Lisp code is returning NULL and how to fix it.

The Root Cause

Your CFFI declaration for wl_display_connect defines the name parameter as :string, but this type expects a Lisp string object. When you pass (null-pointer) to it, CFFI doesn't handle this correctly—it tries to interpret the null pointer as a string, which leads to a mismatched type and the function failing to connect.

In C, passing NULL (a void pointer) to a const char* parameter works because pointers are compatible, but CFFI's type system needs explicit hints to handle this case.

The Fixes

You have two straightforward ways to adjust your CFFI code to match the C behavior:

Option 1: Declare the parameter as :pointer

This lets you directly pass (null-pointer) to represent C's NULL, just like your C code does:

(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)

;; Fix: Change name parameter type to :pointer
(defcfun "wl_display_connect" :pointer
  (name :pointer))

;; Add the disconnect function to clean up resources
(defcfun "wl_display_disconnect" :void
  (display :pointer))

;; Test the connection
(let ((display (wl-display-connect (null-pointer))))
  (if (null-pointer-p display)
      (format *error-output* "Can't connect to display~%")
      (progn
        (format t "connected to display~%")
        (wl-display-disconnect display)
        (format t "disconnected from display~%"))))

Option 2: Use (:nullable :string) for cleaner syntax

CFFI supports nullable types with the :nullable modifier. This lets you pass nil directly, which CFFI automatically converts to a C NULL pointer:

(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)

;; Fix: Use (:nullable :string) to accept nil as NULL
(defcfun "wl_display_connect" :pointer
  (name (:nullable :string)))

(defcfun "wl_display_disconnect" :void
  (display :pointer))

;; Test with nil instead of (null-pointer)
(let ((display (wl-display-connect nil)))
  (if (null-pointer-p display)
      (format *error-output* "Can't connect to display~%")
      (progn
        (format t "connected to display~%")
        (wl-display-disconnect display)
        (format t "disconnected from display~%"))))

Why This Works

Both options align the CFFI type system with the C function's signature:

  • :pointer directly matches the const char* parameter's pointer nature, allowing null pointers to be passed correctly.
  • (:nullable :string) tells CFFI that the string parameter can be NULL, so it safely converts nil to the appropriate C NULL value.

Either approach should resolve the NULL return issue and let you connect to the Wayland display just like your working C code.

内容的提问来源于stack exchange,提问作者C-Entropy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 16:02:36