The cxx Reference Manual

This is the cxx Reference Manual, version 1.0, generated automatically by Declt version 4.0 beta 2 "William Riker" on Mon Feb 26 15:07:13 2024 GMT+0.

Table of Contents


1 Introduction


2 Systems

The main system appears first, followed by any subsystem dependency.


2.1 cxx

Common Lisp Cxx Interoperation

Author

Islam Omar

License

MIT

Long Description

# CL-CXX - Common Lisp wrappers for C++

This library provides an interface to C++ from lisp. It was inspired by Julia’s [libcxxwrap](https://github.com/JuliaInterop/libcxxwrap-julia).

## Prerequisites

- [CLCXX](https://github.com/Islam0mar/CLCXX) is installed

## Installation

Clone into home/common-lisp directory. Then ‘asdf:test-system "cxx"‘

## Supported Types

* Fundamental types
* Pointers
* Classes can add public members and functions
* POD
* functions, std::function and lambda

## Type Conversion

| C++ type | Lisp cffi type | Allocation/copy |
|——————|——————|——————-|
| fundamental | same | copy value |
| POD struct | same | copy value |
| std::string | :string | allocate c string |
| const char* | :string | allocate c string |
| reference | :pointer | copy pointer address |
| class | :pointer | allocate class object |

for allocated memory a finalizer is defined for these objects.

## A Small Example
First you will need to create a C++ glue library that CFF will use when calling C++ functions from Lisp. Compile the code below as a shared library say, libtest.so or libtest.dylib. The commands to do this will vary by compiler and operating system. For testing, it is always good to put the library in the same directory as the lisp code, and ensure that you set the current working directory in your Lisp image. CFFI can take some fiddling to find all the dependencies. This is not unique to this project, all Lisp C/C++ bindings with CFFI have the same requirements.

### The C++ Side of the Equation
“‘c++
#include <string>
#include "clcxx/clcxx.hpp"

std::string greet() { return "Hello, World"; }
int Int(int x) { return x + 100; }
float Float(float y) { return y + 100.34; }
auto gr(std::complex<float> x) { return x; }
std::string hi(char* s) { return std::string("hi, " + std::string(s)); }
void ref_int(int& x) { x += 30; }
void ref_class(xx& x) { x.y = 1000000; }
class xx {
public:
xx(int xx, int yy) : y(yy), x(xx) {}
std::string greet() { return "Hello, World"; }
int y;
int x;
};

CLCXX_PACKAGE TEST(clcxx::Package& pack) {
pack.defun("hi", &hi);
pack.defun("test-int", F_PTR(&Int));
pack.defun("greet", F_PTR(&greet));
pack.defun("test-float", F_PTR(&Float));
pack.defun("test-complex", F_PTR(&gr));
pack.defun("ref-int", F_PTR(&ref_int));
pack.defun("ref-class", F_PTR(&ref_class));
pack.defclass<xx, false>("xx")
.member("y", &xx::y)
.defmethod("foo", F_PTR(&xx::greet))
.defmethod("foo.x", F_PTR([](xx x){return x.x;}))
.constructor<int, int>(); // could be .constructor<int, int>("make-my-xx-class");
}
“‘

### The Lisp Side of Things
You should walk through the commands below in the REPL to get an idea of how the bindings work. Before you start, ensure you have the dependencies loaded:

“‘common lisp
(ql:quickload "cffi")
(ql:quickload "cxx")
“‘

“‘common lisp
(defpackage cxx/test
(:use :cl))
(in-package :cxx/test)

;;; Change the pathname to match that of your system.
(pushnew (merge-pathnames #p"ros/lisp-demo/lib/" (user-homedir-pathname))
cffi:*foreign-library-directories*
:test #’equal)

(cffi:define-foreign-library my-lib
(t (:default "libtest")))

(cffi:use-foreign-library my-lib)

(cxx:init)

(cxx:add-package "TEST" "TEST")

(test:greet)

(test:hi "Cxx")
“‘

## Loading C++ Class

To create a C++ class you should have the following:

- C++
“‘C++
class A {
public:
A(int A, int yy) : y(yy), x(A) {}
int y;
int x;
};
CLCXX_PACKAGE class(clcxx::Package& pack) {
pack.defclass<A, false>("A")
.constructor<int, int>("create-my-A")
.member("y", &A::y)
.member("x", &A::x);
}
“‘
- lisp
“‘common lisp
(defvar my-a-class (class:create-my-A 10 20))
“‘
## Usage

See test files or the [cl-cxx-eigen](https://github.com/Islam0mar/cl-cxx-eigen) project for further examples.

## Architecture
- [CLCXX](https://github.com/Islam0mar/CLCXX) is used to expose ‘C++‘ function/lambda/member_function/overloaded_function to ‘C‘ function pointer that lisp cffi would call.‘C++‘ code is compiled into a shared library –for internals see [CLCXX](https://github.com/Islam0mar/CLCXX)–.

The following steps are expected by this package:
- load ‘C++‘ shared library ‘(cffi:use-foreign-library my-lib)‘.
- call ‘(cxx:init)‘: this function calls ‘clcxx_init(void (*error_handler)(char *), void (*reg_data_callback)(clcxx::MetaData *, uint8_t))‘.
+ ‘error_handler‘ is used to make ‘C++‘ call lisp ‘error‘ function.
+ ‘reg_data_callback‘ is used to pass ‘C‘ function pointer, function paramters types and return type to lisp for registering lisp ‘cffi‘ function.
- call ‘(cxx:add-package "TEST" "TEST")‘: this function calls ‘register_package(const char *cl_pack,void (*regfunc)(clcxx::Package &))‘.
+ ‘cl_pack‘ is the lisp package name.
+ ‘regfunc‘ is the function name in the compiled ‘C++‘ shared library ‘CLCXX_PACKAGE regfunc(clcxx::Package& pack)‘.
- ‘C++‘ package functions are avialable.

### NOTE

Tested on:
* SBCL 1.4.5 on debian
* CCL 1.12 on MacOS 10.13.6

## TODO

- [ ] test functions
- [ ] code refactor
- [ ] global objects sometimes don’t call its finalizers!
- [x] classes
- [x] references
- [ ] Smart pointers
- [ ] Tuple
- [ ] benchmark

## Alternative
- [CL-CXX-JIT](https://github.com/Islam0mar/CL-CXX-JIT) is a new project to make the process easier example: ‘(from ’("<cmath>") ’import ’("static_cast<double(*)(double)>(std::sin)" . "cpp-sin")),‘ then can be called with‘(cpp-sin 0d0)‘. [CL-CXX-JIT](https://github.com/Islam0mar/CL-CXX-JIT) package recompiles c++ files every time, so can be used for quick experimentations, then use ‘cl-cxx‘.

## Copyright

Copyright (c) 2018 Islam Omar (io1131@fayoum.edu.eg)

## License

Licensed under the MIT License.

Version

1.0

Dependencies
  • cffi (system).
  • trivial-garbage (system).
Source

cxx.asd.

Child Components

3 Modules

Modules are listed depth-first from the system components tree.


3.1 cxx/src

Source

cxx.asd.

Parent Component

cxx (system).

Child Components

4 Files

Files are sorted by type and then listed depth-first from the systems components trees.


4.1 Lisp


4.1.1 cxx/cxx.asd

Source

cxx.asd.

Parent Component

cxx (system).

ASDF Systems

cxx.

Packages

cxx/system.


4.1.2 cxx/package.lisp

Source

cxx.asd.

Parent Component

cxx (system).

Packages

cxx.


4.1.3 cxx/src/utilities.lisp

Source

cxx.asd.

Parent Component

src (module).

Internals

4.1.4 cxx/src/c-types.lisp

Source

cxx.asd.

Parent Component

src (module).

Internals

4.1.5 cxx/src/cxx.lisp

Source

cxx.asd.

Parent Component

src (module).

Public Interface
Internals

5 Packages

Packages are listed by definition order.


5.1 cxx

Source

package.lisp.

Use List
  • cffi.
  • common-lisp.
  • trivial-garbage.
Public Interface
Internals

5.2 cxx/system

Source

cxx.asd.

Use List
  • asdf/interface.
  • common-lisp.

6 Definitions

Definitions are sorted by export status, category, package, and then by lexicographic order.


6.1 Public Interface


6.1.1 Ordinary functions

Function: add-package (pack-name func-name)

Register lisp package with pack-name
from func-name defined in ClCxx lib

Package

cxx.

Source

cxx.lisp.

Function: destruct-string (string-to-be-deleted)
Package

cxx.

Source

cxx.lisp.

Function: init ()
Package

cxx.

Source

cxx.lisp.

Function: number-of-allocated-bytes ()
Package

cxx.

Source

cxx.lisp.

Function: remove-package (pack-name)
Package

cxx.

Source

cxx.lisp.


6.2 Internals


6.2.1 Ordinary functions

Function: cffi-type (type)

Returns cffi-type as a keyword or list of keywords

Package

cxx.

Source

cxx.lisp.

Function: clcxx-init (err-callback reg-data-callback)
Package

cxx.

Source

cxx.lisp.

Function: compound-type-list (type &optional array-p)

Returns a list of strings representing compound type

Package

cxx.

Source

cxx.lisp.

Function: get-parenthes-string (string)

Returns a string within first (...) or nil

Package

cxx.

Source

utilities.lisp.

Function: left-trim-string-to (string char)

Returns a string trimmed to char exclusive

Package

cxx.

Source

utilities.lisp.

Function: max-stack-bytes-size ()
Package

cxx.

Source

cxx.lisp.

Function: parse-args (arg-types &optional input-type-p)

return argument types (with variables if they are inputs) in a proper list

Package

cxx.

Source

cxx.lisp.

Function: parse-class (meta-ptr)

Define class

Package

cxx.

Source

cxx.lisp.

Function: parse-class-slots (slot-names slot-types)

Returns super class as symbols in a list

Package

cxx.

Source

cxx.lisp.

Function: parse-constant (meta-ptr)

Define constant

Package

cxx.

Source

cxx.lisp.

Function: parse-cstruct-slots (slot-names slot-types)

Returns super class as symbols in a list

Package

cxx.

Source

cxx.lisp.

Function: parse-function (meta-ptr)

Retruns the function def.

Package

cxx.

Source

cxx.lisp.

Function: parse-super-classes (s)

Returns super class as symbols in a list

Package

cxx.

Source

cxx.lisp.

Function: parse-type (type)

Returns cffi-type as a keyword or list of keywords

Package

cxx.

Source

cxx.lisp.

Function: register-package (name pack-ptr)
Package

cxx.

Source

cxx.lisp.

Function: remove-c-package (name)
Package

cxx.

Source

cxx.lisp.

Function: remove-string (rem-string full-string &key from-end test start1 end1 start2 end2 key)

returns full-string with rem-string removed

Package

cxx.

Source

utilities.lisp.

Function: required (&optional msg &rest args)

If this ever gets called, it means something that was required was not supplied. Use as default value for &key args or defstruct slots.

Package

cxx.

Source

utilities.lisp.

Function: split-string-by (string char)

Returns a list of substrings of string divided by ONE + each.
;; Note: Two consecutive pluses will be seen as ;; if there were an empty string between them.

Package

cxx.

Source

utilities.lisp.

Function: symbols-list (arg-types &optional method-p class-obj)

Return a list of symbols ’(V0 V1 V2 V3 ...) representing the number of args

Package

cxx.

Source

cxx.lisp.


6.2.2 Classes

Class: class-info-tclass
Package

cxx.

Source

c-types.lisp.

Direct superclasses
  • foreign-struct-type.
  • translatable-foreign-type.
Class: constant-info-tclass
Package

cxx.

Source

c-types.lisp.

Direct superclasses
  • foreign-struct-type.
  • translatable-foreign-type.
Class: cxx-complex-tclass
Package

cxx.

Source

c-types.lisp.

Direct superclasses
  • foreign-struct-type.
  • translatable-foreign-type.
Class: function-info-tclass
Package

cxx.

Source

c-types.lisp.

Direct superclasses
  • foreign-struct-type.
  • translatable-foreign-type.

Appendix A Indexes


A.1 Concepts


A.2 Functions

Jump to:   A   C   D   F   G   I   L   M   N   P   R   S  
Index Entry  Section

A
add-package: Public ordinary functions

C
cffi-type: Private ordinary functions
clcxx-init: Private ordinary functions
compound-type-list: Private ordinary functions

D
destruct-string: Public ordinary functions

F
Function, add-package: Public ordinary functions
Function, cffi-type: Private ordinary functions
Function, clcxx-init: Private ordinary functions
Function, compound-type-list: Private ordinary functions
Function, destruct-string: Public ordinary functions
Function, get-parenthes-string: Private ordinary functions
Function, init: Public ordinary functions
Function, left-trim-string-to: Private ordinary functions
Function, max-stack-bytes-size: Private ordinary functions
Function, number-of-allocated-bytes: Public ordinary functions
Function, parse-args: Private ordinary functions
Function, parse-class: Private ordinary functions
Function, parse-class-slots: Private ordinary functions
Function, parse-constant: Private ordinary functions
Function, parse-cstruct-slots: Private ordinary functions
Function, parse-function: Private ordinary functions
Function, parse-super-classes: Private ordinary functions
Function, parse-type: Private ordinary functions
Function, register-package: Private ordinary functions
Function, remove-c-package: Private ordinary functions
Function, remove-package: Public ordinary functions
Function, remove-string: Private ordinary functions
Function, required: Private ordinary functions
Function, split-string-by: Private ordinary functions
Function, symbols-list: Private ordinary functions

G
get-parenthes-string: Private ordinary functions

I
init: Public ordinary functions

L
left-trim-string-to: Private ordinary functions

M
max-stack-bytes-size: Private ordinary functions

N
number-of-allocated-bytes: Public ordinary functions

P
parse-args: Private ordinary functions
parse-class: Private ordinary functions
parse-class-slots: Private ordinary functions
parse-constant: Private ordinary functions
parse-cstruct-slots: Private ordinary functions
parse-function: Private ordinary functions
parse-super-classes: Private ordinary functions
parse-type: Private ordinary functions

R
register-package: Private ordinary functions
remove-c-package: Private ordinary functions
remove-package: Public ordinary functions
remove-string: Private ordinary functions
required: Private ordinary functions

S
split-string-by: Private ordinary functions
symbols-list: Private ordinary functions


A.3 Variables