### Define ASDF System with CFFI Groveller and Wrapper Source: https://cffi.common-lisp.dev/manual/cffi-manual Example ASDF system definition demonstrating the integration of cffi-grovel and cffi-wrapper-file components. This setup allows CFFI to process C code and generate Lisp bindings. ```common-lisp (_defsystem_ "example-software" :defsystem-depends-on ("cffi-grovel") :depends-on ("cffi") :serial t :components ((:file "package") (:cffi-grovel-file "example-grovelling") (:cffi-wrapper-file "example-wrappers") ;; <<--- this part (:file "example"))) ``` -------------------------------- ### Define Foreign Library with Default Options Source: https://cffi.common-lisp.dev/manual/cffi-manual Defines a foreign library named 'libname' and loads it using default conventions. This is a basic example showing how to set up a foreign library. ```common-lisp (define-foreign-library libname) (load-foreign-library 'libname) ``` -------------------------------- ### Conditional Wrapper Definitions with Progn Source: https://cffi.common-lisp.dev/manual/cffi-manual Example of using the `_progn_` macro in CFFI wrappers to conditionally include C code. This specific example includes constants based on the FreeBSD platform. ```common-lisp #+freebsd (_progn_ (constant (ev-enable "EV_ENABLE")) (constant (ev-disable "EV_DISABLE"))) ``` -------------------------------- ### Using `merge-pathnames` with *foreign-library-directories* Source: https://cffi.common-lisp.dev/manual/cffi-manual This example demonstrates using `merge-pathnames` with `user-homedir-pathname` to construct a path to be added to `*foreign-library-directories*` for searching foreign libraries. ```common-lisp (pushnew '(merge-pathnames #p"lisp/libli/" (user-homedir-pathname)) *foreign-library-directories* :test #'equal) (load-foreign-library '(:default "liblibli")) ``` -------------------------------- ### Set Curl Options Example Source: https://cffi.common-lisp.dev/manual/cffi-manual Demonstrates setting specific options for a libcurl easy handle. This includes cleaning up an existing handle, creating a new one, and then setting the NOSIGNAL and URL options. The expected return value for successful option setting is 0. ```common-lisp CFFI-USER> (curl-easy-cleanup *easy-handle*) ⇒ NIL CFFI-USER> (setf *easy-handle* (make-easy-handle)) ⇒ # CFFI-USER> (set-curl-option-nosignal *easy-handle* 1) ⇒ 0 CFFI-USER> (set-curl-option-url *easy-handle* "http://www.cliki.net/CFFI") ⇒ 0 ``` -------------------------------- ### C Code for Inline Functions and Macros Source: https://cffi.common-lisp.dev/manual/cffi-manual C code snippet defining an inline function `foo` and a macro `bar`. These are examples of C constructs that can be wrapped for use in Lisp via CFFI. ```c static inline int foo(int i) { return 1+i; }; #define bar(i) (1+(i)) ``` -------------------------------- ### Define C Structure 'point' with Slots Source: https://cffi.common-lisp.dev/manual/cffi-manual Illustrates defining a C structure named 'point' with two integer slots, 'x' and 'y', using CFFI's defcstruct. Includes an example of initializing and accessing its slots. ```CommonLisp (_defcstruct_ point "Point structure." (x :int) (y :int)) CFFI> (_with-foreign-object_ (ptr 'point) ;; Initialize the slots (setf (foreign-slot-value ptr 'point 'x) 42 (foreign-slot-value ptr 'point 'y) 42) ;; Return a list with the coordinates (_with-foreign-slots_ ((x y) ptr point) (list x y))) ⇒ (42 42) ``` -------------------------------- ### Using *foreign-library-directories* to Add Search Path Source: https://cffi.common-lisp.dev/manual/cffi-manual This example shows how to add a custom directory to the CFFI search path using `pushnew` and `*foreign-library-directories*` before loading a foreign library. ```common-lisp (pushnew #P"/home/sirian/lisp/libli/" *foreign-library-directories* :test #'equal) (load-foreign-library '(:default "liblibli")) ``` -------------------------------- ### Define and Use Callbacks in Common Lisp for C Interaction Source: https://context7.com/context7/cffi_common-lisp_dev_manual/llms.txt Shows how to define Lisp functions (callbacks) that can be called from C code. Includes examples for simple arithmetic callbacks and a comparison callback for `qsort`, demonstrating how to get function pointers and use them. ```lisp ;; Simple callback (defcallback add-callback :int ((a :int) (b :int)) "Add two integers" (+ a b)) ;; Get function pointer CFFI> (callback add-callback) ⇒ # ;; Comparison callback for qsort (defcallback compare-ints :int ((a :pointer) (b :pointer)) (let ((x (mem-ref a :int)) (y (mem-ref b :int))) (cond ((< x y) -1) ((> x y) 1) (t 0)))) (defcfun "qsort" :void (base :pointer) (nmemb :int) (size :int) (compar :pointer)) ;; Sort array using callback CFFI> (with-foreign-object (arr :int 10) ;; Initialize with unsorted values (loop for i from 0 and val in '(7 2 10 4 3 5 1 6 9 8) do (setf (mem-aref arr :int i) val)) ;; Sort using C qsort with Lisp callback (qsort arr 10 (foreign-type-size :int) (callback compare-ints)) ;; Return sorted list (loop for i from 0 below 10 collect (mem-aref arr :int i))) ⇒ (1 2 3 4 5 6 7 8 9 10) ``` -------------------------------- ### Converting Foreign Strings to Lisp Strings in Common Lisp Source: https://cffi.common-lisp.dev/manual/cffi-manual Shows how to convert a foreign string pointer to a Lisp string using `foreign-string-to-lisp`. This example demonstrates retrieving an environment variable's value (a foreign string) and converting it to a Lisp string. ```common-lisp CFFI> (foreign-funcall "getenv" :string "HOME" :pointer) ⇒ # CFFI> (foreign-string-to-lisp *) ⇒ "/Users/luis" ``` -------------------------------- ### Freeing foreign memory allocated by CFFI Source: https://cffi.common-lisp.dev/manual/cffi-manual Demonstrates the use of `foreign-free` to release memory previously allocated using `foreign-alloc`. It shows an example of allocating an integer in foreign memory and then freeing it. ```common-lisp CFFI> (foreign-alloc :int) ⇒ # CFFI> (foreign-free *) ⇒ NIL ``` -------------------------------- ### Call C Function `curl_easy_setopt` using `foreign-funcall` Source: https://cffi.common-lisp.dev/manual/cffi-manual Demonstrates calling the C function `curl_easy_setopt` from Common Lisp using `foreign-funcall`. This example sets the `CURLOPT_NOSIGNAL` option to `1` for a given easy handle. It specifies the C function name, arguments with their C types and Lisp values, and the return type. ```common-lisp (foreign-funcall "curl_easy_setopt" :pointer *easy-handle* curl-option :nosignal :long 1 curl-code) ``` -------------------------------- ### Load a Foreign Library with CFFI Source: https://cffi.common-lisp.dev/manual/cffi-manual Demonstrates loading a foreign library named 'OpenGL' using CFFI's framework loading mechanism on Darwin systems and retrieving its pathname. ```common-lisp (let ((lib (load-foreign-library '(:framework "OpenGL")))) (foreign-library-pathname lib)) ``` -------------------------------- ### Example of CFFI string conversion and foreign function call Source: https://cffi.common-lisp.dev/manual/cffi-manual Demonstrates how a Lisp string is converted to a null-terminated C string using `with-foreign-string` and then passed as a CFFI `:pointer` to a foreign function. This highlights the temporary nature of the C string, which is deallocated upon exiting the macro's body. ```CommonLisp (set-curl-option-url *easy-handle* "http://www.cliki.net/CFFI") ≡ (_with-foreign-string_ (url "http://www.cliki.net/CFFI") (foreign-funcall "curl_easy_setopt" easy-handle *easy-handle* curl-option :url :pointer url curl-code)) ``` -------------------------------- ### Initialize Easy Handle Instance Source: https://cffi.common-lisp.dev/manual/cffi-manual An after-initialize method for the `easy-handle` class. It sets the `error-buffer` slot by allocating memory for the C string and initializing it. ```common-lisp (_defmethod_ initialize-instance :after ((self easy-handle) &key) (set-curl-option-errorbuffer self (slot-value self 'error-buffer))) ``` -------------------------------- ### pointer-eq Source: https://cffi.common-lisp.dev/manual/cffi-manual Compares two foreign pointers for equality of memory addresses, ensuring portability across different Lisp implementations. ```APIDOC ## pointer-eq ### Description The function `pointer-eq` returns true if ptr1 and ptr2 point to the same memory address and false otherwise. It is recommended for portability across different Lisp implementations. ### Method Function ### Endpoint N/A (Function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ``` (pointer-eq (null-pointer) (null-pointer)) ;; => T ``` ### Response #### Success Response (200) - **boolean** (T or NIL) - True if the pointers point to the same address, false otherwise. #### Response Example ``` T ``` ``` -------------------------------- ### Define C Structure with an Array Slot Source: https://cffi.common-lisp.dev/manual/cffi-manual Shows how to define a C structure containing an array using CFFI's defcstruct macro with the :count option. This example defines a 'video_tuner' structure with a character array named 'name' of size 32. ```CommonLisp ;;; Using :count to define arrays inside of a struct. (_defcstruct_ video_tuner (name :char :count 32)) ``` -------------------------------- ### Define C Bitfield with Symbols and Values Source: https://cffi.common-lisp.dev/manual/cffi-manual Demonstrates defining a bitfield for C open flags and retrieving symbols or values from it. Uses CFFI macros for bitfield definition and manipulation. ```CommonLisp (_defbitfield_ open-flags (:rdonly #x0000) :wronly ;#x0001 :rdwr ;… :nonblock :append (:creat #x0200)) ;; etc… CFFI> (foreign-bitfield-symbols 'open-flags #b1101) ⇒ (:WRONLY :NONBLOCK :APPEND) CFFI> (foreign-bitfield-value 'open-flags '(:rdwr :creat)) ⇒ 514 ; #x0202 ``` -------------------------------- ### Define C Function Wrapper for open() Source: https://cffi.common-lisp.dev/manual/cffi-manual Shows how to define a Common Lisp wrapper for the C 'open' function using CFFI. It handles string paths and bitfield flags. Requires CFFI and a C environment. ```CommonLisp (_defcfun_ ("open" unix-open) :int (path :string) (flags open-flags) (mode :uint16)) ; unportable CFFI> (unix-open "/tmp/foo" '(:wronly :creat) #o644) ⇒ # ``` -------------------------------- ### CFFI Typedef Alias Definition (_defctype_) Source: https://cffi.common-lisp.dev/manual/cffi-manual Provides an example of defining a simple C-like typedef alias named 'my-int' for the built-in CFFI type :int using the _defctype_ macro. ```common-lisp ;;; Define MY-INT as an alias for the built-in type :INT. (_defctype_ my-int :int) ``` -------------------------------- ### Calling C printf with CFFI foreign-funcall Source: https://cffi.common-lisp.dev/manual/cffi-manual Illustrates calling the C standard library function 'printf' with format strings and arguments using CFFI's foreign-funcall. This example demonstrates passing string and integer arguments and capturing the return value (number of characters printed). ```common-lisp CFFI> (foreign-funcall "printf" :string (format nil "%s: %d.ப்பின்") :string "So long and thanks for all the fish" :int 42 :int) - | So long and thanks for all the fish: 42. ⇒ 41 ``` -------------------------------- ### Conditional Loading of Foreign Libraries Source: https://cffi.common-lisp.dev/manual/cffi-manual Demonstrates how to define a foreign library that loads conditionally based on Common Lisp features. The library will load differently on Darwin and Unix systems. ```common-lisp (define-foreign-library lib (:darwin "lib.dylib") (:unix "lib.so") (t "lib.dll")) ``` -------------------------------- ### Calling C variadic function sprintf with CFFI foreign-funcall-varargs Source: https://cffi.common-lisp.dev/manual/cffi-manual Shows how to call a C variadic function like 'sprintf' using CFFI's foreign-funcall-varargs. This example formats a double-precision float into a string buffer and returns the number of characters written. ```common-lisp CFFI> (_with-foreign-pointer-as-string_ (s 100) (setf (mem-ref s :char) 0) (foreign-funcall-varargs "sprintf" (:pointer s :string) "%.2f" :double (coerce pi 'double-float) :int)) ⇒ 3.14 ``` -------------------------------- ### Macroexpansion Example for _define-curl-options_ in Common Lisp Source: https://cffi.common-lisp.dev/manual/cffi-manual This code snippet shows the result of macroexpanding the `_define-curl-options_` macro for the `curl-option` type. It defines the `curl-option` CFFI enum with specific values and then defines corresponding setter functions using `_define-curl-option-setter_` for options like `noprogress`, `nosignal`, `errorbuffer`, and `url`. ```common-lisp (_progn_ (_defcenum_ curl-option (:noprogress 43) (:nosignal 99) (:errorbuffer 10010) (:url 10002)) (_define-curl-option-setter_ set-curl-option-noprogress curl-option :noprogress :long) (_define-curl-option-setter_ set-curl-option-nosignal curl-option :nosignal :long) (_define-curl-option-setter_ set-curl-option-errorbuffer curl-option :errorbuffer :pointer) (_define-curl-option-setter_ set-curl-option-url curl-option :url :pointer) 'curl-option) ``` -------------------------------- ### Free Easy Handle Resources Source: https://cffi.common-lisp.dev/manual/cffi-manual A function `free-easy-handle` to free the resources associated with an `easy-handle`, including the C pointer and any C strings allocated for its options. ```common-lisp (_defun_ free-easy-handle (handle) "Free CURL easy interface HANDLE and any C strings created to be its options." (_with-slots_ (pointer error-buffer c-strings) handle ``` -------------------------------- ### Define and Get Foreign Library Callback Pointer Source: https://cffi.common-lisp.dev/manual/cffi-manual Defines a Lisp function as a callback accessible from C, and retrieves a pointer to this callback. Arguments are converted to Lisp, and the return value to C. Ensure defcallback is a top-level form for portability. ```common-lisp ;; Define a callback named SUM that returns an integer and takes two integers. ;; The body of the callback adds the two arguments. (defcallback sum :int ((a :int) (b :int)) (+ a b)) ;; Retrieve a pointer to the defined callback 'sum'. ;; This pointer can be used in C code to call the Lisp function. (callback sum) ``` -------------------------------- ### Define a Foreign Library with CFFI Source: https://cffi.common-lisp.dev/manual/cffi-manual The `define-foreign-library` macro is used to describe to CFFI how to load a foreign library. It specifies the library name and optionally provides platform-specific loading clauses and search paths. ```common-lisp (define-foreign-library libcurl (t (:default "libcurl"))) ``` -------------------------------- ### Get Callback Pointer in Common Lisp Source: https://cffi.common-lisp.dev/manual/cffi-manual Illustrates how to define a callback using `_defcallback_` and then obtain a pointer to that callback using the `get-callback` function. This pointer can be used when interfacing with foreign functions. ```common-lisp (CFFI> (_defcallback_ sum :int ((a :int) (b :int)) (+ a b)) ⇒ SUM CFFI> (get-callback 'sum) ⇒ # ``` -------------------------------- ### Allocating Foreign Strings with Common Lisp Source: https://cffi.common-lisp.dev/manual/cffi-manual Illustrates the use of `foreign-string-alloc` to allocate memory for a C-style string from a Lisp string. It shows how to get a pointer to the allocated memory and verify its length using `strlen`. ```common-lisp CFFI> (_defparameter_ *str* (foreign-string-alloc "Hello, foreign world!")) ⇒ # CFFI> (foreign-funcall "strlen" :pointer *str* :int) ⇒ 21 ``` -------------------------------- ### Define Foreign Libraries with Dependencies and Error Handling in Common Lisp Source: https://context7.com/context7/cffi_common-lisp_dev_manual/llms.txt Illustrates defining multiple foreign libraries with dependencies and includes an example of error handling during library loading using `handler-case`. ```lisp (define-foreign-library openssl (:unix (:or "libssl.so.1.1" "libssl.so.1.0.0" "libssl.so")) (:windows "libssl-1_1-x64.dll") (t (:default "libssl"))) (define-foreign-library crypto (:unix (:or "libcrypto.so.1.1" "libcrypto.so.1.0.0" "libcrypto.so")) (:windows "libcrypto-1_1-x64.dll") (t (:default "libcrypto"))) ;; Load dependencies in order (use-foreign-library crypto) (use-foreign-library openssl) ;; With error handling (handler-case (load-foreign-library 'openssl) (load-foreign-library-error (e) (format t "Failed to load OpenSSL: ~A~%" e) (return-from load-crypto-libs nil))) ``` -------------------------------- ### Lispier Wrapper for C open() Function Source: https://cffi.common-lisp.dev/manual/cffi-manual Presents a more idiomatic Common Lisp function 'lispier-open' that wraps the C 'open' function defined via CFFI. It simplifies argument passing for flags. ```CommonLisp ;;; Consider also the following lispier wrapper around open() (_defun_ lispier-open (path mode &rest flags) (unix-open path flags mode)) ``` -------------------------------- ### Define Foreign Library with Specific Features and Paths Source: https://cffi.common-lisp.dev/manual/cffi-manual Defines a foreign library 'libname' that loads differently based on the 'feature-expression'. It specifies a search path for the library and uses the ':cdecl' calling convention. ```common-lisp (define-foreign-library libname (:darwin "libname.dylib") (:unix (:default "libname.so")) :library-foreign-symbol "sym" ; optional :dependency (:runtime "libdependency.so") ; optional :default-foreign-library "libname.dll" :default-loading-options '(:cdecl)) ``` -------------------------------- ### with-foreign-pointer Source: https://cffi.common-lisp.dev/manual/cffi-manual Allocates a block of foreign memory of a specified size and binds it to a variable within a dynamic scope. ```APIDOC ## with-foreign-pointer ### Description The `with-foreign-pointer` macro binds var to size bytes of foreign memory during body. The pointer in var is invalid beyond the dynamic extend of body and may be stack-allocated if supported by the implementation. If size-var is supplied, it will be bound to size during body. ### Method Macro ### Endpoint N/A (Macro) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ``` (with-foreign-pointer (string 4 size) (setf (mem-ref string :char (1- size)) 0) (lisp-string-to-foreign "Popcorns" string size) (loop for i from 0 below size collect (code-char (mem-ref string :char i)))) ;; => (#\P #\o #\p #\Null) ``` ### Response #### Success Response (200) - **result** - The result of the body forms. #### Response Example ``` (#\P #\o #\p #\Null) ``` ``` -------------------------------- ### foreign-type-alignment Source: https://cffi.common-lisp.dev/manual/cffi-manual Retrieves the alignment of a foreign type in bytes. ```APIDOC ## FOREIGN-TYPE-ALIGNMENT ### Description The function `foreign-type-alignment` returns the alignment of `type` in bytes. ### Method Function ### Endpoint N/A ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```lisp (foreign-type-alignment :char) ; ⇒ 1 (foreign-type-alignment :short) ; ⇒ 2 (foreign-type-alignment :int) ; ⇒ 4 (defcstruct foo (a :char)) (foreign-type-alignment '(:struct foo)) ; ⇒ 1 ``` ### Response #### Success Response (200) - **alignment** (integer) - The alignment of the type in bytes. #### Response Example ```lisp 1 2 4 1 ``` ### See Also foreign-type-size ``` -------------------------------- ### Defining my-string type with expand-to-foreign-dyn Source: https://cffi.common-lisp.dev/manual/cffi-manual This snippet defines methods for the 'my-string' type using expand-from-foreign and expand-to-foreign-dyn. It optimizes string handling for dynamic extent, reducing overhead in function calls. ```common-lisp (_defmethod_ expand-from-foreign (form (type my-string-type)) `(foreign-string-to-lisp ,form)) (_defmethod_ expand-to-foreign-dyn (value var body (type my-string-type)) (_let_ ((encoding (string-type-encoding type))) `(_with-foreign-string_ (,var ,value :encoding ',encoding) ,@body))) ``` -------------------------------- ### free-converted-object Source: https://cffi.common-lisp.dev/manual/cffi-manual Frees a foreign object that was converted from a Lisp object. ```APIDOC ## FREE-CONVERTED-OBJECT ### Description This is an external interface to the type translation facility. In the implementation, all foreign functions are ultimately defined as type translation wrappers around primitive foreign function invocations. This function is available mostly for inspection of the type translation process, and possibly optimization of special cases of your foreign function calls. Its behavior is better described under `free-translated-object`’s documentation. ### Method Function ### Endpoint N/A ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```lisp (convert-to-foreign "a boat" :string) ;; ⇒ # ;; ⇒ T (free-converted-object * :string t) ;; ⇒ NIL ``` ### Response #### Success Response (200) - **unspecified** - The return value is unspecified. #### Response Example ```lisp NIL ``` ### See Also convert-from-foreign convert-to-foreign free-translated-object ``` -------------------------------- ### Define Common Lisp Bitfield with CFFI-Grovel Source: https://cffi.common-lisp.dev/manual/cffi-manual Defines a bitfield structure using CFFI-Grovel. It specifies Lisp names, corresponding C names, optional flags, and documentation. The name-and-opts can be a symbol or a list with a base type. ```common-lisp (bitfield flags-ctype ((:flag-a "FLAG_A") :documentation "DOCU_A") ((:flag-b "FLAG_B" "FLAG_B_ALT") :documentation "DOCU_B") ((:flag-c "FLAG_C") :documentation "DOCU_C" :optional t)) ``` -------------------------------- ### Loading a Foreign Library Source: https://cffi.common-lisp.dev/manual/cffi-manual This is a basic function call to load a foreign library using its designator. The function returns a `foreign-library` object upon successful loading. ```common-lisp (load-foreign-library '(:default "libname")) ``` -------------------------------- ### CFFI Type Specification Parsing (_define-parse-method_) Source: https://cffi.common-lisp.dev/manual/cffi-manual Demonstrates how to define a method for parsing type specifications like '(my-string :encoding :utf8)' into an instance of a custom foreign type class ('my-string-type') using _define-parse-method_. ```common-lisp (_define-parse-method_ my-string (&key (encoding :utf-8)) (make-instance 'my-string-type :encoding encoding)) ``` -------------------------------- ### Load CFFI Grovel and Create Static Program Source: https://cffi.common-lisp.dev/manual/cffi-manual Common Lisp code to load the CFFI grovel system and then operate on a specified ASDF system to create a statically linked standalone application executable. This bundles C extensions into a single executable file. ```common-lisp (asdf:load-system :cffi-grovel) (asdf:operate :static-program-op :example-software) ``` -------------------------------- ### Get Foreign Pointer Address in Common Lisp with CFFI Source: https://cffi.common-lisp.dev/manual/cffi-manual Shows how to retrieve the memory address of a foreign pointer using the `pointer-address` function in CFFI. Examples include getting the address of a null pointer and a pointer created with `make-pointer`. ```common-lisp CFFI> (pointer-address (null-pointer)) ⇒ 0 CFFI> (pointer-address (make-pointer 123)) ⇒ 123 ``` -------------------------------- ### Defining my-boolean type with expand-to-foreign and expand-from-foreign Source: https://cffi.common-lisp.dev/manual/cffi-manual This snippet demonstrates defining a custom 'my-boolean' type in CFFI using the expand-to-foreign and expand-from-foreign generic functions. It shows how to handle boolean conversions to and from C integers. ```common-lisp (_define-foreign-type_ my-boolean-type () () (:actual-type :int) (:simple-parser my-boolean)) (_defmethod_ expand-to-foreign (value (type my-boolean-type)) `(_if_ ,value 1 0)) (_defmethod_ expand-from-foreign (value (type my-boolean-type)) `(not (zerop ,value))) ``` -------------------------------- ### Common Lisp Package Definitions for CFFI Projects Source: https://cffi.common-lisp.dev/manual/cffi-manual Defines Common Lisp packages, including an internal package for CFFI definitions and an external package for the main system. It demonstrates exporting symbols and managing dependencies between packages, advising against using `:use` directly to prevent name clashes. ```common-lisp (_defpackage_ #:example-internal (:use) (:nicknames #:exampleint)) (_defpackage_ #:example-software (:export ...) (:use #:cl #:cffi #:exampleint)) ``` -------------------------------- ### Macroexpansion of define-curl-option-setter in Common Lisp Source: https://cffi.common-lisp.dev/manual/cffi-manual This snippet shows the result of macroexpanding a `define-curl-option-setter` form. It generates a CFFI `defcfun` for `curl_easy_setopt` and a helper function to curry the setter. It is used to simplify setting curl options through FFI. ```common-lisp (_progn_ (_defcfun_ ("curl_easy_setopt" set-curl-option-nosignal) curl-code (easy-handle easy-handle) (option curl-option) (new-value :long)) (curry-curl-option-setter 'set-curl-option-nosignal ':nosignal)) ``` -------------------------------- ### Macroexpansion of _defcfun_ with optimized my-string Source: https://cffi.common-lisp.dev/manual/cffi-manual This snippet shows the macroexpansion of a CFFI function definition using the 'my-string' type with optimized dynamic extent handling. It demonstrates the use of _with-foreign-string_ for efficient string translation. ```common-lisp CFFI> (macroexpand-1 '(_defcfun_ foo my-string (x my-string))) ;; (simplified, downcased, etc...) (_defun_ foo (x) (_with-foreign-string_ (#:G2021 X :encoding ':utf-8) (foreign-string-to-lisp (foreign-funcall "foo" :pointer #:g2021 :pointer)))) ``` -------------------------------- ### ASDF System Definition with CFFI-Grovel Integration Source: https://cffi.common-lisp.dev/manual/cffi-manual Defines an ASDF system, specifying dependencies on CFFI-Grovel and CFFI. It uses `(:cffi-grovel-file)` and `(:cffi-wrapper-file)` for custom component types, ensuring CFFI-Grovel is processed correctly. The `eval-when` directive ensures CFFI-Grovel is available during system definition. ```common-lisp ;;; CFFI-Grovel is needed for processing grovel-file components (_defsystem_ "example-software" :defsystem-depends-on ("cffi-grovel") :depends-on ("cffi") :serial t :components ((:file "package") (:cffi-grovel-file "example-grovelling") (:cffi-wrapper-file "example-wrappers") (:file "example"))) ``` -------------------------------- ### with-foreign-slots Source: https://cffi.common-lisp.dev/manual/cffi-manual A macro similar to Common Lisp's `with-slots` that creates local symbol macros for referencing foreign slots within a structure pointed to by a foreign pointer. ```APIDOC ## with-foreign-slots ### Description The `with-foreign-slots` macro creates local symbol macros for each var in vars to reference foreign slots in ptr of type. If the var is a list starting with `:pointer`, it will bind the pointer to the slot (rather than the value). It is similar to Common Lisp’s `with-slots` macro. ### Method Macro ### Endpoint N/A (Macro) ### Parameters #### Arguments - **vars** - A list with each element a symbol, or list of length two with the first element `:pointer` and the second a symbol. - **ptr** - A foreign pointer to a structure. - **type** - A structure type. - **body** - A list of forms to be executed. ### Usage Example ```lisp (with-foreign-slots (slot1 (:pointer ptr-sym) slot2) ptr structure-type ;; Use slot1, ptr-sym, and slot2 here ) ``` -------------------------------- ### Define C Structure with Custom Class in Common Lisp Source: https://cffi.common-lisp.dev/manual/cffi-manual Defines a C structure 'person' with associated Common Lisp class 'c-person'. This allows for specialized translation methods for the structure. ```common-lisp (_defcstruct_ (person :class c-person) (number :int) (reason :string)) ``` -------------------------------- ### Load CFFI Grovel and Create Static Image Source: https://cffi.common-lisp.dev/manual/cffi-manual Common Lisp code to load the CFFI grovel system and then operate on a specified ASDF system to create a statically linked Lisp executable image. This bundles C extensions into the final image. ```common-lisp (asdf:load-system :cffi-grovel) (asdf:operate :static-image-op :example-software) ``` -------------------------------- ### Check for Null Pointer in Common Lisp with CFFI Source: https://cffi.common-lisp.dev/manual/cffi-manual Demonstrates how to check if a given pointer is a null pointer using the `null-pointer-p` function in CFFI. This is useful for verifying the validity of foreign pointers before dereferencing them. ```common-lisp CFFI> (null-pointer-p (null-pointer)) ⇒ T ``` -------------------------------- ### CFFI Complex Foreign Type Definition (_define-foreign-type_) Source: https://cffi.common-lisp.dev/manual/cffi-manual Shows the initial step in defining a more complex foreign type 'my-string' with an 'encoding' parameter using _define-foreign-type_. This sets up a type class with :actual-type specified as :pointer. ```common-lisp (_define-foreign-type_ my-string-type () ((encoding :reader string-type-encoding :initarg :encoding)) (:actual-type :pointer)) ``` -------------------------------- ### Define libcurl Easy Handle Functions (init/cleanup) with CFFI Source: https://cffi.common-lisp.dev/manual/cffi-manual Defines CFFI bindings for `curl_easy_init` and `curl_easy_cleanup`. `curl_easy_init` returns a pointer representing the CURL easy handle, and `curl_easy_cleanup` takes this pointer to free resources. These are fundamental for managing libcurl sessions. ```common-lisp (_defcfun_ "curl_easy_init" :pointer) (_defcfun_ "curl_easy_cleanup" :void (easy-handle :pointer)) ``` -------------------------------- ### Check if an Object is a Foreign Pointer in Common Lisp with CFFI Source: https://cffi.common-lisp.dev/manual/cffi-manual Demonstrates the usage of the `pointerp` function in CFFI to determine if an object is a foreign pointer. It shows examples with a foreign pointer allocated by CFFI and a standard string. ```common-lisp CFFI> (foreign-alloc 32) ⇒ # CFFI> (pointerp *) ⇒ T CFFI> (pointerp "this is not a pointer") ⇒ NIL ``` -------------------------------- ### Update curl.h Options Definition with Write Function Source: https://cffi.common-lisp.dev/manual/cffi-manual This Common Lisp code snippet demonstrates how to extend CFFI's `define-curl-options` to include the `writefunction` option, mapping it to the correct numerical type (`functionpoint`) and value. ```common-lisp (_define-curl-options_ curl-option (long 0 objectpoint 10000 functionpoint 20000 off-t 30000) (:noprogress long 43) (:nosignal long 99) (:errorbuffer objectpoint 10) (:url objectpoint 2) (:writefunction functionpoint 11)) ; New item defining writefunction ``` -------------------------------- ### Macroexpansion of _defcfun_ with my-string type Source: https://cffi.common-lisp.dev/manual/cffi-manual This snippet shows the macroexpansion of a CFFI function definition using a custom 'my-string' type. It illustrates the overhead introduced by generic function calls for type translation. ```common-lisp CFFI> (macroexpand-1 '(_defcfun_ foo my-string (x my-string))) ;; (simplified, downcased, etc...) (_defun_ foo (x) (multiple-value-bind (#:G2019 #:PARAM3149) (translate-to-foreign x #) (_unwind-protect_ (translate-from-foreign (foreign-funcall "foo" :pointer #:G2019 :pointer) #) (free-translated-object #:G2019 # #:PARAM3149)))) ``` -------------------------------- ### Define CFFI Wrappers for Inline Functions and Macros Source: https://cffi.common-lisp.dev/manual/cffi-manual Common Lisp code demonstrating the use of the `_defwrapper_` macro to create bindings for C inline functions and macros. It specifies the wrapper name, return type, and argument types. ```common-lisp (in-package :mypackage) (_defwrapper_ ("foo" foo) :int (i :int)) (_defwrapper_ ("bar" bar) :int (i :int)) ``` -------------------------------- ### Define C struct and use C functions with Common Lisp via CFFI Source: https://cffi.common-lisp.dev/manual/cffi-manual Defines a C structure 'tm' and demonstrates how to allocate memory for it, call the C 'time' and 'gmtime' functions, and access its fields. This involves using CFFI macros like _defcstruct_, _with-foreign-object_, and _with-foreign-slots_. ```common-lisp (_defcstruct_ tm (sec :int) (min :int) (hour :int) (mday :int) (mon :int) (year :int) (wday :int) (yday :int) (isdst :boolean) (zone :string) (gmtoff :long)) CFFI> (_with-foreign-object_ (time :int) (setf (mem-ref time :int) (foreign-funcall "time" :pointer (null-pointer) :int)) (foreign-funcall "gmtime" :pointer time (:pointer (:struct tm)))) ⇒ # CFFI> (_with-foreign-slots_ ((sec min hour mday mon year) * (:struct tm)) (format nil "~A:~A:~A, ~A/~A/~A" hour min sec (+ 1900 year) mon mday)) ⇒ "7:22:47, 2005/8/2" ``` -------------------------------- ### Managing C strings with easy handles using hash tables Source: https://cffi.common-lisp.dev/manual/cffi-manual Introduces a system for managing the lifetime of C strings associated with `curl` easy handles. It uses a hash table (`*easy-handle-cstrings*`) to store lists of C strings for each handle, ensuring they are freed when the handle is cleaned up. ```CommonLisp (_defvar_ *easy-handle-cstrings* (make-hash-table) "Hashtable of easy handles to lists of C strings that may be safely freed after the handle is freed.") ``` ```CommonLisp (_defun_ make-easy-handle () "Answer a new CURL easy interface handle, to which the lifetime of C strings may be tied. See `add-curl-handle-cstring'." (_let_ ((easy-handle (curl-easy-init))) (setf (gethash easy-handle *easy-handle-cstrings*) '()) easy-handle)) ``` ```CommonLisp (_defun_ free-easy-handle (handle) "Free CURL easy interface HANDLE and any C strings created to be its options." (curl-easy-cleanup handle) (mapc #'foreign-string-free (gethash handle *easy-handle-cstrings*)) (remhash handle *easy-handle-cstrings*)) ``` ```CommonLisp (_defun_ add-curl-handle-cstring (handle cstring) "Add CSTRING to be freed when HANDLE is, answering CSTRING." (car (push cstring (gethash handle *easy-handle-cstrings*)))) ``` -------------------------------- ### Compare Foreign Pointers for Equality in Common Lisp with CFFI Source: https://cffi.common-lisp.dev/manual/cffi-manual Illustrates the use of the `pointer-eq` function in CFFI for comparing two foreign pointers. It highlights the importance of `pointer-eq` for reliable pointer comparison across different Lisp implementations, contrasting it with standard equality predicates. ```common-lisp CFFI> (eql (null-pointer) (null-pointer)) ⇒ NIL CFFI> (pointer-eq (null-pointer) (null-pointer)) ⇒ T ``` -------------------------------- ### Get Easy Handle Error Message Source: https://cffi.common-lisp.dev/manual/cffi-manual A function `get-easy-handle-error` to retrieve the error message from an `easy-handle`'s error buffer. It converts the C string in the buffer to a Lisp string. ```common-lisp (_defun_ get-easy-handle-error (handle) "Answer a string containing HANDLE's current error message." (foreign-string-to-lisp (slot-value handle 'error-buffer))) ``` -------------------------------- ### CFFI Foreign Slot Offset Source: https://cffi.common-lisp.dev/manual/cffi-manual Demonstrates `foreign-slot-offset` to get the byte offset of a specific slot within a CFFI structure type. This is crucial for manual memory manipulation or understanding structure layout. ```CommonLisp (_defcstruct_ timeval (tv-secs :long) (tv-usecs :long)) CFFI> (foreign-slot-offset '(:struct timeval) 'tv-secs) ⇒ 0 CFFI> (foreign-slot-offset '(:struct timeval) 'tv-usecs) ⇒ 4 ``` -------------------------------- ### Execute and Capture URL Content in Common Lisp Source: https://cffi.common-lisp.dev/manual/cffi-manual This Common Lisp code snippet demonstrates how to execute the previously defined `curl-easy-perform` function and capture its output. It utilizes `with-output-to-string` and a custom `*easy-write-procedure*` to collect the fetched HTML content. This pattern is useful for web scraping or fetching data from external resources. ```common-lisp (with-output-to-string (contents) (let ((*easy-write-procedure* (lambda (string) (write-string string contents)))) (declare (special *easy-write-procedure*)) (curl-easy-perform *easy-handle*))) ``` -------------------------------- ### Get Foreign Type Size in CFFI Source: https://cffi.common-lisp.dev/manual/cffi-manual Calculates the size in bytes of a foreign type, including any padding necessary for array representations. Essential for memory allocation and manipulation when interfacing with C data types. ```common-lisp (_defcstruct_ foo (a :double) (c :char)) CFFI> (foreign-type-size :double) ⇒ 8 CFFI> (foreign-type-size :char) ⇒ 1 CFFI> (foreign-type-size '(:struct foo)) ``` -------------------------------- ### Get Foreign Type Alignment in CFFI Source: https://cffi.common-lisp.dev/manual/cffi-manual Returns the memory alignment in bytes for a given foreign type. This is important for correct memory layout when interacting with C structures. Supports primitive types and defined CFFI structures. ```common-lisp CFFI> (foreign-type-alignment :char) ⇒ 1 CFFI> (foreign-type-alignment :short) ⇒ 2 CFFI> (foreign-type-alignment :int) ⇒ 4 ``` ```common-lisp (_defcstruct_ foo (a :char)) CFFI> (foreign-type-alignment '(:struct foo)) ``` -------------------------------- ### Get Pointer to Foreign Variable (Common Lisp) Source: https://cffi.common-lisp.dev/manual/cffi-manual Returns a pointer to a foreign global variable that was previously defined using `defcvar`. This function is useful when you need to pass the address of a foreign variable to another C function. ```Common Lisp (_defcvar_ "errno" :int :read-only t) ``` ```Common Lisp (get-var-pointer '*errno*) ``` ```Common Lisp (mem-ref * :int) ``` -------------------------------- ### Get Foreign Slot Pointer in CFFI Source: https://cffi.common-lisp.dev/manual/cffi-manual Retrieves a pointer to a specific slot within a foreign object. Useful for direct memory manipulation or when dealing with aggregate slots. It requires the foreign object pointer, its CFFI type, and the slot name. ```common-lisp (_defcstruct_ point "Pointer structure." (x :int) (y :int)) CFFI> (_with-foreign-object_ (ptr '(:struct point)) (foreign-slot-pointer ptr '(:struct point) 'x)) ``` -------------------------------- ### Define C Foreign Function and Callback in Common Lisp Source: https://cffi.common-lisp.dev/manual/cffi-manual Demonstrates how to define a foreign function signature using `_defcfun_` and create a callback function using `_defcallback_`. It also shows how to use these definitions with `_with-foreign-object_`, `qsort`, and `callback` to sort an array. ```common-lisp (_defcfun_ "qsort" :void (base :pointer) (nmemb :int) (size :int) (fun-compar :pointer)) (_defcallback_ < :int ((a :pointer) (b :pointer)) (_let_ ((x (mem-ref a :int)) (y (mem-ref b :int))) (_cond_ ((> x y) 1) ((< x y) -1) (t 0)))) (CFFI> (_with-foreign-object_ (array :int 10) ;; Initialize array. (_loop_ for i from 0 and n in '(7 2 10 4 3 5 1 6 9 8) do (setf (mem-aref array :int i) n)) ;; Sort it. (qsort array 10 (foreign-type-size :int) (callback <)) ;; Return it as a list. (_loop_ for i from 0 below 10 collect (mem-aref array :int i))) ⇒ (1 2 3 4 5 6 7 8 9 10) ```