[cffi-devel] First usages of CFFI
Marko Tapio Manninen
mmstud at gmail.com
Tue Jun 17 00:59:12 UTC 2008
Hi,
so far i have compiled some programs, that use CFFI, but now id like
to create my own. As usual i counter my limits of knowledge and hope
to find some answers here. I'm using libevent library (later doing
same with libev), that has a simple event based server application,
which i want to use from ccl / sbcl. I'll put two c functions first,
and then some header information and finally some lisp code i have
created. Im particularry interested getting some comments, how the
work should be done. Yet there re two parts of the code, where i have
stuck and they are:
void evhttp_set_gencb(struct evhttp *http, void (*cb)(struct
evhttp_request *, void *), void *cbarg) {}
(defcfun ("evhttp_set_gencb" %evhttp-set-gencb) :void
(http evhttp)
???)
Actually same part occurs on evbuffer:
void (*cb)(struct evbuffer *, size_t, size_t, void *);
Regards,
-Marko
--------------------------------------------------------------------------------------------------------------------------------------
// ACTUAL APPLICATION
void generic_handler(struct evhttp_request *req, void *arg)
{
struct evbuffer *buf;
buf = evbuffer_new();
if (buf == NULL)
err(1, "failed to create response buffer");
evbuffer_add_printf(buf, "Requested: %sn",
evhttp_request_uri(req));
evhttp_send_reply(req, HTTP_OK, "OK", buf);
}
int main(int argc, char **argv)
{
struct evhttp *httpd;
event_init();
httpd = evhttp_start("0.0.0.0", 5007);
/* Set a callback for requests to "/specific". */
/* evhttp_set_cb(httpd, "/specific", another_handler, NULL); */
/* Set a callback for all other requests. */
evhttp_set_gencb(httpd, generic_handler, NULL);
event_dispatch();
/* Not reached in this code as it is now. */
evhttp_free(httpd);
return 0;
}
// SOME C CODE TO DEFINE
#define HTTP_OK 200
struct evhttp;
struct evhttp_request;
struct evbuffer {
u_char *buffer;
u_char *orig_buffer;
size_t misalign;
size_t totallen;
size_t off;
void (*cb)(struct evbuffer *, size_t, size_t, void *);
void *cbarg;
};
struct event_base * event_init(void) {}
struct evhttp * evhttp_start(const char *address, u_short port) {}
void evhttp_free(struct evhttp* http) {}
void evhttp_set_gencb(struct evhttp *http, void (*cb)(struct
evhttp_request *, void *), void *cbarg) {}
// LISP PART
(cffi:define-foreign-library libevent
(:darwin "libevent.dylib")
(t (:default "libevent")))
(cffi:use-foreign-library libevent)
(defconstant HTTP_OK 200)
(defconstant HTTP_NOCONTENT 204)
(defconstant HTTP_MOVEPERM 301)
(defconstant HTTP_MOVETEMP 302)
(defconstant HTTP_NOTMODIFIED 304)
(defconstant HTTP_BADREQUEST 400)
(defconstant HTTP_NOTFOUND 404)
(defconstant HTTP_SERVUNAVAIL 503)
(defctype size-t :unsigned-int)
(defcstruct evbuffer
(*buffer :unsigned-char)
(*orig_buffer :unsigned-char)
(misalign size-t)
(totallen size-t)
(off size-t)
(*cb :pointer) ; struct?
(*cbarg :pointer))
(defcstruct event-base)
(defcstruct evhttp-request)
(defcstruct evhttp)
(defcfun ("evbuffer_new" %evbuffer-new) :pointer)
(defcfun ("evbuffer_add_printf" %evbuffer-add-printf) :void
(buf evbuffer)
(msg :string)
(uri :string))
(defcfun ("evhttp_request_uri" %evhttp-request-uri) :string
(req evhttp-request))
(defcfun ("evhttp_send_reply" %evhttp-send-reply) :void
(req evhttp-request)
(flag :int)
(msg :string)
(buf evbuffer))
;;; unwind-protect to create evbuffer-new?
(defun generic-handler (req &optional (arg nil))
(let ((buf (%evbuffer-new)))
(if (null buf)
(error "Failed to create response buffer")
(progn
(%evbuffer-add-printf buf "Requested: %sn" (%evhttp-request-uri
req))
(%evhttp-send-reply req HTTP_OK "OK" buf)))))
(defcfun ("event_init" %event-init) :event-base)
(defcfun ("evhttp_start" %evhttp-start) :evhttp
(address :char)
(port :unsigned-short))
(defcfun ("evhttp_set_gencb" %evhttp-set-gencb) :void
(http evhttp)
???)
(defcfun ("event_dispatch" %event-dispatch) :int)
(defcfun ("evhttp_free" %evhttp-free) :void
(http evhttp))
;;; MAIN SERVER START UP FUNCTION
;(server "0.0.0.0" 5009)
(defun server (host port)
(%event-init)
(let ((httpd %evhttp-start host port)
(%evhttp-set-gencb httpd #'generic-handler nil)
(%event-dispatch)
(%evhttp-free httpd))))
More information about the cffi-devel
mailing list