Calling C++ (not C) from Common Lisp?


Question

I am wondering if there is some way to call C++ code from Common Lisp (preferably portably, and if not, preferably in SBCL, and if not, well, then Clozure, CLisp or ECL).

The C++ would be called inside loops for numeric computation, so it would be nice if calls were fast.

CFFI seems to not support this:

"The concept can be generalized to other languages; at the time of writing, only CFFI's C support is fairly complete, but C++ support is being worked on."

(chapter 4 of the manual)

SBCL's manual doesn't mention C++ either; it actually says

This chapter describes SBCL's interface to C programs and libraries (and, since C interfaces are a sort of lingua franca of the Unix world, to other programs and libraries in general.)

The C++ code uses OO and operator overloading, so it really needs to be compiled with g++.

And as far as I know, I can have a C++ main() function and write wrappers for C functions, but not the other way around -- is that true?

Anyway... Is there some way to do this?

Thank you!

1
13
9/7/2009 3:18:40 AM

Accepted Answer

Oh, wait!

It seems that there is a trick I can use!

I write a wrapper in C++, declaring wrapper functions extern "C":

#include "lib.h"

extern "C" int lib_operate (int i, double *x) {
...
}

The header file lib.h, which can be called from both C and C++, is:

#if __cplusplus
extern "C" {
#endif

int lib_operate (int i, double *x);

#if __cplusplus
}
#endif

Then compile with:

g++ -c lib.cpp
gcc -c prog.c
gcc lib.o prog.o -lstdc++ -o prog

Seems to work for a toy example! :-)

So, in Common Lisp I'd call the wrapper after loading libstdc++.

Anyway, thank you for your answers!

6
9/5/2009 11:51:14 AM

After compiling, most C++ functions actually boil down to regular C function calls. Due to function overloading and other features, C++ compilers use name mangling to distinguish between similarly named functions. Given an object dump utility and sufficient knowledge about your C++ compiler, you can call C++ code directly from the outside world.

Having said that though, you may find it easier to write a C-compatible layer between Lisp and your C++ code. You would do that using extern "C" like this:

extern "C" Foo *new_Foo(int x)
{
    return new Foo(x);
}

This makes the new_Foo() function follow the C calling convention so that you can call it from external sources.


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon