【问题标题】:How to create a Lisp FLI function corresponding to a C macro如何创建对应于 C 宏的 Lisp FLI 函数
【发布时间】:2023-03-08 11:05:01
【问题描述】:

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

我尝试将其定义如下,但被告知 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)

【问题讨论】:

    标签: lisp c-preprocessor common-lisp ffi lispworks


    【解决方案1】:

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

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

    #define HIGHWORD(x)     /* whatever */
    
    int 
    highword_wrapper(int x)
    {
        return HIGHWORD(x);
    }
    

    这个可以和FFI一起使用。

    【讨论】:

      【解决方案2】:

      无需跳入另一种语言。 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.
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-20
        • 1970-01-01
        • 1970-01-01
        • 2012-04-27
        相关资源
        最近更新 更多