common-lisp - 具有 SBCL 外部接口(interface)的 Win32 MessageBox

标签 common-lisp sbcl cffi

我试图弄清楚如何使用 SBCL 外部接口(interface)调用 Win32 函数 MessageBox。 MessageBox function在“user32.dll”中实现的描述如下:

int MessageBox(
  [in, optional] HWND    hWnd,
  [in, optional] LPCTSTR lpText,
  [in, optional] LPCTSTR lpCaption,
  [in]           UINT    uType
);

[...]

MB_OK 0x00000000L The message box contains one push button: OK. This is the default. 

使用 cffi library 使用此函数很简单:

(cffi:load-foreign-library '(:default "user32"))

(cffi:defcfun ("MessageBoxA" message-box) :int
  (hwnd    :pointer)
  (text    :string)
  (caption :string)
  (type    :unsigned-int))

(message-box (cffi:null-pointer) "Hello" "Test" 0)

我尝试直接通过 SBCL 接口(interface) sb-alien 使用此函数:我无法使其工作。

(sb-alien:load-shared-object "user32")

(defvar c-null (sb-sys:int-sap 0))

(sb-alien:define-alien-routine ("MessageBoxA" MessageBox) sb-alien:int
  (hwnd    (* sb-alien:integer))
  (text    sb-alien:c-string)
  (caption sb-alien:c-string)
  (uType   (sb-alien:unsigned 4)))

;; need a small wrapper to convert Lisp's strings to foreign
(defun message-box (title message)
  (let ((title-alien   (sb-alien:make-alien-string title))
        (message-alien (sb-alien:make-alien-string message)))
    (MessageBox c-null title-alien message-alien 0)
    (sb-alien:free-alien title-alien)
    (sb-alien:free-alien message-alien)))

(message-box "Hello" Test")

没有任何错误或警告,但它不起作用。 SBCL 外星人接口(interface)工作如何?我尝试阅读 CFFI 和 SBCL 中的代码,但找不到任何简单的示例。

最佳答案

我不明白我怎么能在这个问题上花费整个下午,但字符串实际上是自动从/到 Lisp 转换的。所以代码其实很简单:

(sb-alien:load-shared-object "user32")

(defvar c-null (sb-sys:int-sap 0))

(define-alien-routine ("MessageBoxA" MessageBox) sb-alien:integer
  (hwnd    (* sb-alien:integer))
  (text    sb-alien:c-string)
  (caption sb-alien:c-string)
  (uType   (sb-alien:unsigned 4)))

(MessageBox c-null "Hello" "Test" 0)

关于common-lisp - 具有 SBCL 外部接口(interface)的 Win32 MessageBox,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73358925/

相关文章:

dll - 从 lisp 脚本、工作目录和路径加载库

lisp - 如何在 Lisp 中对 1000 以下可被 3 或 5 整除的所有数字求和?

emacs - SLIME 和 Quicklisp 相处得不好

python - 使用 CFFI 构建 Python-C 扩展,但 Setuptools 不在构建中包含自定义头文件

common-lisp - 如何使用输出指针参数调用外部函数?

set - Common Lisp 中的 Mandelbrot Set 实现

testing - 在测试包中访问包的内部符号

vim - 新的 SLIMV 0.8.4 安装,paren 匹配有效,缩进没有

3 的倍数的 Lisp 总和

common-lisp - 代码在 SLIME+SBCL 中运行,但不是普通的 SBCL