Search code examples
lispc-preprocessorcommon-lispffilispworks

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


I want to create a lisp function which corresponds to a macro in C. e.g., there is one HIWORD in win32 API, which is defined as a macro in the header file.

I tried to define it as below but was told that HIWORD is unresolved.

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

I just want to know how to create a wrapper for C macros like for C functions.

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

Solution

  • No need to jump into another language. Shifting and masking in Lisp:

    (defun hiword (val)
      (logand (ash val -16) #xFFFF)
    
    (defun loword (val) ;; ditto
      (logand val #xFFFF))
    

    Another way: using the ldb accessor with ranges expressed using byte syntax:

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