UFFI has functions to two types of C
-compatible
strings: cstring and foreign
strings. cstrings are used only as parameters to
and from functions. In some implementations a cstring is not a foreign
type but rather the Lisp string itself. On other platforms a cstring
is a newly allocated foreign vector for storing characters. The
following is an example of using cstrings to both send and return a
value.
(uffi:def-function ("getenv" c-getenv) ((name :cstring)) :returning :cstring) (defun my-getenv (key) "Returns an environment variable, or NIL if it does not exist" (check-type key string) (uffi:with-cstring (key-native key) (uffi:convert-from-cstring (c-getenv key-native))))
In contrast, foreign strings are always a foreign vector of characters which have memory allocated. Thus, if you need to allocate memory to hold the return value of a string, you must use a foreign string and not a cstring. The following is an example of using a foreign string for a return value.
(uffi:def-function ("gethostname" c-gethostname) ((name (* :unsigned-char)) (len :int)) :returning :int) (defun gethostname () "Returns the hostname" (let* ((name (uffi:allocate-foreign-string 256)) (result-code (c-gethostname name 256)) (hostname (when (zerop result-code) (uffi:convert-from-foreign-string name)))) ;; UFFI does not yet provide a universal way to free ;; memory allocated by C's malloc. At this point, a program ;; needs to call C's free function to free such memory. (unless (zerop result-code) (error "gethostname() failed."))))
Foreign functions that return pointers to freshly allocated strings should in general not return cstrings, but foreign strings. (There is no portable way to release such cstrings from Lisp.) The following is an example of handling such a function.
(uffi:def-function ("readline" c-readline) ((prompt :cstring)) :returning (* :char)) (defun readline (prompt) "Reads a string from console with line-editing." (with-cstring (c-prompt prompt) (let* ((c-str (c-readline c-prompt)) (str (convert-from-foreign-string c-str))) (uffi:free-foreign-object c-str) str)))
Table of Contents