cl-cxx
cl-cxx copied to clipboard
README Improvements
I found this in my search for common lisp CFFI bindings to Boost mathematical libraries. On the surface this seems related, but I can't be sure. Perhaps a bit more explanation in the README, and a note about how this would be used for a binding?
@Symbolics I think this is what you need: cl-cxx-eigen
You can use the same way to add boost functions.
Sorry for the late response as I was traveling for 2 months.
This looks like it has a lot of potential. Is this an experiment or proof of concept, or have you been able to use it to wrap a large library. On the surface it seems to solve a lot of the problems encountered in wrapping lisp, as many libraries seem to be written exclusively in C++ these days.
I think it has no problem to wrap large library such as eigen lib.
#include <clcxx/clcxx.hpp>
#include <string>
#include "clcxx_eigen.hpp"
CLCXX_PACKAGE EIGEN(clcxx::Package& pack) {
using EigenMat = EigenMatWrapper<Eigen::MatrixXd, double>;
pack.defclass<EigenMat, true>("Matrix")
.constructor<Eigen::Index, Eigen::Index>()
.defmethod("m.resize",
static_cast<void (EigenMat::*)(Eigen::Index, Eigen::Index)>(
&EigenMat::resize))
.defmethod("m.block", &EigenMat::getBlock)
.defmethod("m.row", &EigenMat::getRow)
.defmethod("m.col", &EigenMat::getCol)
.defmethod("m.size", &EigenMat::size)
.defmethod("m.rows", &EigenMat::rows)
.defmethod("m.cols", &EigenMat::cols)
.defmethod("m.get-at-index", &EigenMat::get)
.defmethod(
"m.set-at-index",
static_cast<void (EigenMat::*)(Eigen::Index, Eigen::Index, double)>(
&EigenMat::set))
.defmethod(
"m.set-matrix",
static_cast<void (EigenMat::*)(const EigenMat&)>(&EigenMat::set))
.defmethod("m.set-zero", &EigenMat::set0)
.defmethod("m.set-ones", &EigenMat::set1)
.defmethod("m.set-identity", &EigenMat::setId)
.defmethod("%m.set-from-array", &EigenMat::setFromArray)
.defmethod("m.trace", &EigenMat::trace)
.defmethod("m.sum", &EigenMat::sum)
.defmethod("m.prod", &EigenMat::prod)
.defmethod("m.mean", &EigenMat::mean)
.defmethod("m.norm", &EigenMat::norm)
.defmethod("m.squared-norm", &EigenMat::squaredNorm)
.defmethod("m.print", &EigenMat::print)
.defmethod("m.scale", &EigenMat::scale)
.defmethod("m.add-scalar",
static_cast<void (EigenMat::*)(const double&)>(&EigenMat::add))
.defmethod("m.add-mat", static_cast<void (EigenMat::*)(const EigenMat&)>(
&EigenMat::add))
.defmethod("m.multiply", &EigenMat::multiply)
.defmethod("m.inverse", &EigenMat::inv)
.defmethod("m.full-inverse", &EigenMat::mInv)
.defmethod("m.transpose", &EigenMat::trans)
.defmethod("m.determinant", &EigenMat::det)
.defmethod("m.full-determinant", &EigenMat::mDet)
.defmethod("m.rank", &EigenMat::rankLU)
.defmethod("m.full-q", &EigenMat::mQ)
.defmethod("m.full-p", &EigenMat::mP)
.defmethod("m.p", &EigenMat::squareMP)
.defmethod("m.l", &EigenMat::squareML)
.defmethod("m.u", &EigenMat::squareMU)
.defmethod("m.lower-Cholesky", &EigenMat::mLCholesky)
.defmethod("m.upper-Cholesky", &EigenMat::mUCholesky)
.defmethod("m.eigen-values", &EigenMat::eigenVals)
.defmethod("m.full-solve", &EigenMat::solveLU)
.defmethod("m.solve", &EigenMat::solveSquareLU)
.defmethod("m.solve-Cholesky", &EigenMat::solveCholesky)
.defmethod("m.full-lower", &EigenMat::mU)
.defmethod("m.full-upper", &EigenMat::mL);
pack.defun("m*", [](const EigenMat& x, const EigenMat& y) -> EigenMat {
return static_cast<EigenMat>(x * y);
});
pack.defun("m+", [](const EigenMat& x, const EigenMat& y) -> EigenMat {
return static_cast<EigenMat>(x + y);
});
}
for my work it was acceptable.
Try to wrap your large library.
Pull request #4 will also bring in some documentation improvements, though I think more documentation is required than I have knowledge to write.
Could you specify the documentation parts that would be added?
I would suggest a few sections:
Introduction - Explain where the concepts were taken from, (Julia), high level description of how it works. limitation Architecture - Block diagram, sequence diagrams for the calls from Lisp to C++ Examples - 2 or 3 end to end examples, with extensive documentation Future Direction - What is planned next, if anything. E.g. Auto-wrap style wrapping so you can point to a header. Roadmap for the C++ features that are missing. Help Wanted - what can contributors help with, by skill level.
cl-cuda and cl-autowrap have pretty good documentation and would be useful as a guide.
You might also consider contacting rpav to see if this could somehow be folded into cl-autowrap.
The example of cl-cxx doesn't show how to instantiate classes, set slots and use class methods. Could you specify how this is done? I need this for a port to link and it'd be amazing if I could get it working (the lib already compiles...)!
The following code doesn't work here after loading the compiled lib from the example into lisp:
(cxx:add-package "TEST" "TEST") ;;; ok so far
(defparameter *test* (make-instance 'test::xx)) ;;; ok, but the CXX-CLASS-PTR slot of *test* is NIL
(setf (slot-value *test* 'test::y 32)) ;;; works
(test::foo *test*) ;;; doesn't work:
-> The value
NIL
is not of type
SB-SYS:SYSTEM-AREA-POINTER
when binding SB-ALIEN::VALUE
To load a C++ class you have to call it's constructor function that is exposed from C++pack.defclass<xx, false>("xx").constructor<int, int>()
, so in this example it would be called test:create-xx2
-> (test:create-xx2 1 3)
.
Now (make-instance 'test::xx)
should give you an error message to call c++ constructor function.
I forked your repository, created a new branch "documentation-added", added an extensive README and a working full example. I'm going to add more examples in scratch.lisp but basically it should be done. Before issuing a merge request I'd like to get your opinion, suggestions, etc.
I added the README in a new doc
folder. It's completely rewritten according to the suggestions of @Symbolics . Feel free to merge with your own README, replace it or leave it in the doc folder, pointing to it or whatever. Hope you like it. It's my attempt at thanking you for your help and work, expecially in the recent week!!!
Thanks a bunch. looks great.
@ormf Could you please open a PR from your fork?