Next: , Previous: Tutorial-Loading, Up: Tutorial


4.4 Initializing 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.