cl-webengine - QtWebEngine binding for Common Lisp Bindings to Qt and WebEngine.
How it Works Common Lisp has a way to interact with C code via the so called CFFI (C Foreign Function Interface). This interface allows any C code to be called by Common Lisp. At this time, there is no universal foreign function interface for C++. This presents a problem when we wish to call Qt code (which is written in C++).
In order to circumvent this problem, we can write functions in C that call the C++ code that we need. Concretely it looks like this:
In this way, we can now invoke C++ through Lisp. A concrete example is shown below for a single function:
** interface.h
extern "C" void widgetShow(void* widget);
** interface.cpp
void widgetShow(void widget) { QWidget _widget = reinterpret_cast<QWidget*>(widget); _widget->show(); }
** interface.lisp
(defcfun ("widgetShow" widget-show) :void (widget :pointer)) (export 'widget-show)
The library requires Qt5 and Qt5 Webengine. More specifically, you don't need all of Qt5, the following Qt5 components are enough:
qtbase
qtwebengine
qtwebchannel
qtdeclarative
Compilation
make all
After compiling, you will need to copy the shared libraries to a location where CFFI can find them. If you need to append a location for CFFI, you can add the following lines to your Lisp initialization:
(ql:quickload :cffi) (pushnew "/opt/local/lib/" cffi:foreign-library-directories :test #'equal)
The above demonstrates an example in SBCL, where the location of the shared library will be in =/opt/local/lib=.
Running in SBCL on macOS:
(sb-int:with-float-traps-masked (:invalid :inexact :overflow) (cl-webengine::run))
Running from SLIME in SBCL on macOS:
(trivial-main-thread:call-in-main-thread (lambda () (sb-int:with-float-traps-masked (:invalid :inexact :overflow) (cl-webengine::run))))