如何创建对应于 C 宏的 Lisp FLI 函数

How to create a Lisp FLI function corresponding to a C macro

我想创建一个对应于 C 中的宏的 lisp 函数。 例如win32中有一个HIWORDAPI,在头文件中定义为一个宏

我尝试如下定义它,但被告知 HIWORD 未解析。

CL-USER 4 > (hiword #xFFFFFFFF)
Error: Foreign function HIWORD trying to call to unresolved external function "HIWORDW".

我只想知道如何像为 C 函数一样为 C 宏创建包装器。

(fli:define-c-typedef DWORD (:unsigned :long))
(fli:define-c-typedef WORD (:unsigned :short))

(fli:define-foreign-function
        (HIWORD "HIWORD" :dbcs)
        ((dwVal dword))
        :result-type word :calling-convention :stdcall)

您不能直接执行此操作。 C 预处理器宏不会在编译过程中保留,即在生成的目标文件中根本没有工件,这将对应于 C 宏本身(尽管它的扩展可能多次成为目标文件的一部分)。由于没有工件,因此没有任何东西可以与 FFI 绑定。

但是,您可以提供包装函数

#define HIGHWORD(x)     /* whatever */

int 
highword_wrapper(int x)
{
    return HIGHWORD(x);
}

并且这个可以与 FFI 一起使用。

无需跳转到另一种语言。 Lisp 中的移位和掩码:

(defun hiword (val)
  (logand (ash val -16) #xFFFF)

(defun loword (val) ;; ditto
  (logand val #xFFFF))

另一种方式:使用 ldb 访问器和使用 byte 语法表示的范围:

(defun hiword (val)
  (ldb (byte 16 16) val)  ;; get 16-bit-wide "byte" starting at bit 16.

(defun loword (val)
  (ldb (byte 16 0) val)   ;; get 16-bit-wide "byte" at position 0.