libcurl
After the introductory matter, the tutorial goes on to present the first function you should use.
CURLcode curl_global_init(long flags);
Let's pick this apart into appropriate Lisp code:
;;; A CURLcode is the universal error code. curl/curl.h says ;;; no return code will ever be removed, and new ones will be ;;; added to the end. (defctype curl-code :int) ;;; Initialize libcurl with FLAGS. (defcfun "curl_global_init" curl-code (flags :long))
Implementor's note: By default, CFFI assumes the UNIX viewpoint that there is one C symbol namespace, containing all symbols in all loaded objects. This is not so on Windows and Darwin, but we emulate UNIX's behaviour there. defcfun for more details.
Note the parallels with the original C declaration. We've defined
curl-code
as a wrapping type for :int
; right now, it
only marks it as special, but later we will do something more
interesting with it. The point is that we don't have to do it yet.
Looking at curl.h, CURL_GLOBAL_NOTHING
, a possible value
for flags
above, is defined as ‘0’. So we can now call
the function:
cffi-user> (curl-global-init 0)
=> 0
Looking at curl.h again, 0
means CURLE_OK
, so it
looks like the call succeeded. Note that CFFI converted the
function name to a Lisp-friendly name. You can specify your own name
if you want; use ("curl_global_init"
your-name-here)
as
the name argument to defcfun
.
The tutorial goes on to have us allocate a handle. For good measure, we should also include the deallocator. Let's look at these functions:
CURL *curl_easy_init( ); void curl_easy_cleanup(CURL *handle);
Advanced users may want to define special pointer types; we will explore this possibility later. For now, just treat every pointer as the same:
(defcfun "curl_easy_init" :pointer) (defcfun "curl_easy_cleanup" :void (easy-handle :pointer))
Now we can continue with the tutorial:
cffi-user> (defparameter *easy-handle* (curl-easy-init)) => *EASY-HANDLE* cffi-user> *easy-handle* => #<FOREIGN-ADDRESS #x09844EE0>
Note the print representation of a pointer. It changes depending on what Lisp you are using, but that doesn't make any difference to CFFI.