Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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)
like image 260
user1461328 Avatar asked Nov 20 '25 08:11

user1461328


2 Answers

You cannot do this directly. C preprocessor macros are not preserved in the compilation process, i.e., there is simply no artifact in the generated object files, which would correspond to the C macro itself (though its expansion may be part of the object file multiple times). And since there is no artifact, there is nothing to bind to with FFI.

You can, however, provide a wrapper function

#define HIGHWORD(x)     /* whatever */

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

and this one can be used with FFI.

like image 79
Dirk Avatar answered Nov 23 '25 12:11

Dirk


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.
like image 37
Kaz Avatar answered Nov 23 '25 11:11

Kaz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!