use*_*328 3 lisp common-lisp ffi c-preprocessor lispworks
我想创建一个与C中的宏对应的lisp函数.例如,win32 API中有一个HIWORD,它被定义为头文件中的一个宏.
我尝试将其定义如下,但被告知HIWORD尚未解决.
CL-USER 4 > (hiword #xFFFFFFFF)
Error: Foreign function HIWORD trying to call to unresolved external function "HIWORDW".
Run Code Online (Sandbox Code Playgroud)
我只是想知道如何为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)
Run Code Online (Sandbox Code Playgroud)
你不能直接这样做.C预处理器宏不会在编译过程中保留,即生成的目标文件中根本没有工件,这对应于C宏本身(尽管它的扩展可能是目标文件的一部分多次).由于没有工件,因此没有任何东西可以与FFI绑定.
但是,您可以提供包装函数
#define HIGHWORD(x) /* whatever */
int
highword_wrapper(int x)
{
return HIGHWORD(x);
}
Run Code Online (Sandbox Code Playgroud)
这个可以和FFI一起使用.
无需跳入另一种语言.在Lisp中移位和屏蔽:
(defun hiword (val)
(logand (ash val -16) #xFFFF)
(defun loword (val) ;; ditto
(logand val #xFFFF))
Run Code Online (Sandbox Code Playgroud)
另一种方法:使用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.
Run Code Online (Sandbox Code Playgroud)