Lisp and its FFI
Learning some Lisp recently and found that it has a very approachable FFI. I had a need for a MQTT client to publish some messages and decided to go with the native mosquitto client library rather than rely on some of the existing lisp solutions. So given that the native interfaces look like these
libmosq_EXPORT int mosquitto_publish(struct mosquitto * mosq,
int * mid,
const char * topic,
int payloadlen,
const oid * payload,
int qos,
bool retain)
libmosq_EXPORT struct mosquitto *mosquitto_new(const char * id,
bool clean_session,
void * obj)
libmosq_EXPORT void mosquitto_destroy(struct mosquitto * mosq)
This is all that I would need to use the native mosquitto library and publish a message.
(ql:quickload :cffi)
(cffi:defcfun ("mosquitto_new" %mosquitto-new)
:pointer
(id :string)
(clean-session :int)
(obj :pointer))
(cffi:defcfun ("mosquitto_connect" %mosquitto-connect)
:int
(mosq :pointer)
(host :string)
(port :int)
(keepalive :int))
(cffi:defcfun ("mosquitto_publish" %mosquitto-publish)
:int
(mosq :pointer)
(mid :pointer)
(topic :string)
(payloadlen :int)
(payload :string)
(qos :int)
(retain :int))
(cffi:defcfun ("mosquitto_destroy" %mosquitto-destroy)
:void
(mosq :pointer))
(cffi:use-foreign-library "libmosquitto.so")
(defun publish-mqtt-message (host port keepalive topic payload qos retain)
(let ((handle (%mosquitto-new (cffi:null-pointer) 1 (cffi:null-pointer))))
(%mosquitto-connect handle host port keepalive)
(%mosquitto-publish handle (cffi:null-pointer) topic (length payload)
payload qos retain)
(%mosquitto-destroy handle)))
(publish-mqtt-message "localhost" 1883 60 "test/topic" "hello, world!" 0 0)
Sometimes its a lot simpler to build your own client wrappers rather than to use a pre-existing library. In my case, I want a very small subset of the features and don’t want the mental burden of learning a whole library.