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!
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.
The main difference in calling C++ functions instead of C functions apart from the name mangling are the 'hidden' features like this pointers that are implicitly passed to member functions. The C runtime layer doesn't know anything about these, implicit type conversions and other fun C++ features, so if you intend to call C++ through a C interface, you might have to fake these features if necessary.
Assuming that you can hold at least a void * to the object you intend to call and the data it requires, you can degrade the following C++ call
matrix->multiply(avector);
to a C call if you create a C wrapper function:
extern "C"
void matrix_multiply(void *cpp_matrix, void *cpp_vector) {
reinterpret_cast<matrix_type *>(cpp_matrix)->multiply(reinterpret_cast<vector_type *>(cpp_vector);
}
Obviously the function matrix_multiply would sit in the C++ source code and compiled as such but it does expose a C interface to the outside world. As long as you can interact with the opaque pointers, you're OK with the translation shims above.
Admittedly this is not necessarily the most elegant solution for a problem like this but I've used it in the past in situations like yours.
The other option would be to make the C++ calls directly by treating them as C calls with additional parameters and supplying all the required information yourself, but that does move you into the realm of compiler-specific code very quickly. Basically, you would still be holding the opaque pointers to C++ objects, but you'd have to work out the mangled name of the function you want to call. Once you've got that function name, you'll have to supply the this pointer (which is implicit in C++ and semi-implicit in the example above) and the correct parameters and then call the function. It can be done but as mentioned, puts you deeply in to the realm of compiler and even compiler-version specific behaviour.
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!
Update 2021:CL-CXX-JIT which handles most of the work on the lisp side.
Example:
(ql:quickload :cxx-jit)
(in-package cxx-jit)
(from '("<cmath>") 'import '("static_cast<double(*)(double)>(std::sin)" . "cpp-sin"))
(cpp-sin 0d0)
(from nil 'import "struct C{ auto hi(){return \"Hello, World\\n\";} auto bye(){return \"Bye\";} };" '("&C::bye" . "bye") '("&C::hi" . "hi") '("[](){static C x; return x;}" . "cc"))
(cc)
(hi *)
(bye **)
You can use cl-cxx which is like writing pybind11 for python.
example in c++ 'std >= c++14', compiled as shared lib:
#include <string>
#include "clcxx/clcxx.hpp"
class xx {
public:
xx(int xx, int yy) : y(yy), x(xx) {}
std::string greet() { return "Hello, World"; }
int y;
int x;
};
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_class(xx& x) { x.y = 1000000; }
CLCXX_PACKAGE TEST(clcxx::Package& pack) {
pack.defun("hi", F_PTR(&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-class", F_PTR(&ref_class));
pack.defclass<xx, false>("xx")
.member("y", &xx::y)
.defmethod("greet-from-class", F_PTR(&xx::greet))
.constructor<int, int>();
}
usage in lisp:
(cffi:use-foreign-library my-lib)
(cxx:init)
(cxx:add-package "TEST" "TEST")
(test:greet)
(setf my-class (test:create-xx2 10 20))
(test:y.get myclass)
That would take care of all conversions, extern "C", ... for you.
Depending on your C++ ABI, your wrapper (lib_operate above) might need to somehow handle any C++ exceptions that might occur. If your ABI does table-drive exception handling, unhandled exceptions will simply crash the (Lisp) process. If it instead does dynamic registration, you might not even notice that anything went wrong. Either way, it's bad.
Or, if you've got the no-throw guarantee for the wrapped code, you can ignore all this.
Related
NOTE: This is not about C/C++ linkage or the extern keyword. Please read carefully before associating my question with seemingly similar questions, thank you!
I think this is a somewhat unusual problem as I didn't find anything on this while browsing the web.
I'm programming an embedded system. The main module is written in C while a submodule is written in C++. To illustrate this:
submodule.hpp
/ \
/ \
main.c submodule.cpp
Now I want to hold on to the data that is used by the C++-submodule and contain it in a static variable in my main script so I can call submodule functions from main and provide context data with every call. But that data must also contain a class as it is used by the submodule functions, but of course C doesn't know how to deal with classes. So I have to covertly put a class into my C-struct without main.c-script noticing (giving me an error). How could I achieve this?
I figured something like this could work:
struct data_for_cpp_submodule {
int a;
int b;
void *class;
}
And then casting the void pointer "class" back to the appropriate class so I can work with it in the C++ script. Could this work or am I going about it completely the wrong way?
Please, note that OP emphasized:
The main module is written in C while a submodule is written in C++.
IMHO, it's completely fine to add a C binding for the C++ submodule, so that it can be used in C code.
The example of OP (enhanced a bit to make it an MCVE):
C++ code for submodule:
header submodule.hpp:
#ifndef SUB_MODULE_HPP
#define SUB_MODULE_HPP
class Test {
private:
int a = 0;
int b = 0;
public:
Test() = default; // default constructor
Test(int a, int b): a(a), b(b) { } // value constructor
Test(Test&) = delete; // say: copy constructor disabled
Test& operator=(Test&) = delete; // say: copy assignment disabled
public:
int exec() const;
};
#endif // SUB_MODULE_HPP
source submodule.cpp:
#include "submodule.hpp"
int Test::exec() const { return a + b + 42; }
C Binding for submodule:
header: submodule.h
#ifndef SUB_MODULE_H
#define SUB_MODULE_H
#ifdef __cplusplus
extern "C" {
#endif
struct TestC_;
typedef struct TestC_ TestC; // opaque structure
extern TestC* testNew();
extern TestC* testNewValues(int a, int b);
extern void testDelete(TestC *pTest);
extern int testExec(TestC *pTest);
#ifdef __cplusplus
}
#endif
#endif // SUB_MODULE_H
source submoduleC.cpp:
#include "submodule.h"
#include "submodule.hpp"
TestC* testNew() { return (TestC*)new Test(); }
TestC* testNewValues(int a, int b) { return (TestC*)new Test(a, b); }
void testDelete(TestC *pTest) { delete (Test*)pTest; }
int testExec(TestC *pTest) { return ((Test*)pTest)->exec(); }
Last but not least: A sample C program using submodule:
#include <stdio.h>
#include "submodule.h"
int main(void)
{
TestC *pTest = testNew();
printf("pTest->exec(): %d\n", testExec(pTest));
testDelete(pTest);
pTest = testNewValues(123, -123);
printf("pTest->exec(): %d\n", testExec(pTest));
testDelete(pTest);
}
How it has to be compiled and linked with g++/gcc:
$ ## compile C++ code
$ g++ -std=c++17 -O2 -Wall -pedantic -c submodule.cpp submoduleC.cpp
$ ## compile C code
$ gcc -std=c11 -O2 -Wall -pedantic -lstdc++ main.c submodule.o submoduleC.o
$ ## test
$ ./a.out
Output:
testExec(pTest): 42
testExec(pTest): 42
Demo on coliru
The most notable part might be the opaque structure:
struct TestC_;
typedef struct TestC_ TestC; // opaque structure
(This is what I learnt from other C bindings before I started to write my own.)
It might be surprising that the opaque structure is actually an incomplete structure but that's intentional.
The opaque structure is intended to be used as pointer only in C. It's not intended to allow dereferencing of any contents (and, for an incomplete structure, this is merely denied by the compiler). It's only purpose is to "tunnel" a pointer to a C++ Test instance through the C code.
In the C binding of Test (submoduleC.cpp), TestC* is simply converted to Test* (and vice versa) where necessary.
Hint:
I had to link -lstdc++ (the standard C++ library). Otherwise, I got complaints about undefined references for the operators new and delete:
submoduleC.o: In function `testNew':
submoduleC.cpp:(.text+0xa): undefined reference to `operator new(unsigned long)'
submoduleC.o: In function `testNewValues':
submoduleC.cpp:(.text+0x30): undefined reference to `operator new(unsigned long)'
submoduleC.o: In function `testDelete':
submoduleC.cpp:(.text+0x4b): undefined reference to `operator delete(void*, unsigned long)'
collect2: error: ld returned 1 exit status
Other thoughts (but probably not that relevant):
I remember a prominent framework which
is written in C
and provides a C++ API (aka. C++ binding).
I'm talking about GTK+ and gtkmm (its C++ binding).
Thereby, it should be mentioned that GTK+ is actually an OOP library – providing object-oriented classes implemented in C. (I'm uncertain whether this fact makes things easier or harder concerning the C++ binding.)
Both are Open Source projects. Hence, everybody can have a look at it how did they do. I once had a look and was impressed…
This aside, I always would recommend the opposite: writing a library in C++ and adding a C binding as this appears much easier to me.
We always did this in Windows for multiple reasons:
to achieve that DLLs compiled with different versions of Visual Studio can be linked together. (Until soon, this was nearly impossible with C++ but now, I believe, I read about an ABI introduced by Microsoft which may it make possible.)
to provide a base for bindings in other languages like e.g. C#.
I need to use the mbed api but limited to using C. How can I use for example a SPI class in a c file. From looking online to use C++ classes you should create a wrapper function in C++ but as stated I can't use C++, is their another way around this?
How can I use for example a SPI class in a c file.
You cannot use a class† in C.
From looking online to use C++ classes you should create a wrapper function in C++
This is correct.
is their another way around this?
No.
but as stated I can't use C++
Then you're out of options (as far as the standards are concerned). A C++ API (with classes and everything) cannot be used in C. It is possible to create a wrapper interface that uses only features shared by both languages (which excludes all OOP stuff).
That wrapper interface can only be implemented in C++, because it has to interact with the interface that it is wrapping. If the wrapper could be implemented in C, then there would be no need for it. Once that wrapper interface is implemented, it can be used from C.
Some other points:
If a library uses C++, then main must be implemented in C++. That main can also be a trivial wrapper for a C function, which can be called from C++ without fuss.
You must link the dependencies of the C++ library, which may include the C++ standard library
Example:
C++ API
// interface.hpp
class C {
public:
std::string str;
};
C wrapper for the API
// wrapper.h
struct C;
struct C* makeC();
void freeC(struct C*);
void setStr(struct C*, char*);
conts char* getStr(struct C*);
Implementation of the wrapper (in C++)
extern "C" {
#include "wrapper.h"
}
#include "interface.hpp"
C* makeC() { return new C; }
void freeC(C* c) { delete c; }
void setStr(C* c, char* str) { c->str = str; }
const char* getStr(C* c) { return c->str.c_str(); }
Usage in C
struct C* c = makeC();
setStr(c, "test");
puts(getStr(c));
freeC(c);
†Except when the class definition and all of its sub objects use no C++ features whatsoever. Then it is compatible with an identical C struct.
The mbed HAL is written in C, so you can use that without the C++ wrappers. E.g. here is hal/spi_api.h.
Answer is simply - using mbed involves using C++.
If you have to program in C forget about mbed and write your own SPI library or use one of the many available libraries (frameworks) for your target hardware.
There is no other way
If you are limited to use C... just use C and compile it as a C++ file. Most code shall be compatible.
I have the following c++ program:
Client.h
#ifndef Client_Client_h
#define Client_Client_h
#include "Client.h"
class Client {
public:
void f1();
void f2();
};
#endif
Client.cpp
#include <iostream>
#include <stdlib.h>
using namespace std;
#include "Client.h"
void Client::f1(){
cout << "Client.f1()" << endl;
}
void Client::f2() {
cout << "Client.f2()" << endl;
}
compiling the above in XCode 4.3 gives me a static library file called:
libClient.a
Separately, I have a main.c
#include <stdio.h>
//
//using namespace std;
int main(){
// how do I do something like: Client c; c.f1(); c.f2();
// and actually get output ?
printf("hello\n");
return 0;
}
What's steps do I need to take in order to invoke f1() and f2() ? How do I use GCC to link the static library properly?
So far I have tried:
gcc -lClient.a main.c
which gives me :
ld: library not found for -lClient.a
collect2: ld returned 1 exit status
This isn't going to work, or at least is not going to be portable. The one really really obvious thing to do is to make your program C++ so you can access those features.
You can't "natively" use C++ code from C code, for obvious reasons. You don't have access to object-oriented features, so a ton of stuff isn't going to work: constructors, destructors, move/copy semantics and virtual inheritance are probably the biggest things that you'll miss. (That's right: you won't be able to create or destroy objects correctly, unless they have trivial constructors and destructors.)
You'll also run into linkage issues: C++ function names are mangled into a mess that includes their parameter types and return types and classes, which will look like __1cGstrcpy6Fpcpkc_0_. It would be technically feasible to declare the mangled names of the functions in C to use them, or use dlsym to get a pointer to them, but that's plain silly. Don't do that.
If you need to create a function in C++ that needs to be callable from C, you can specify it as extern "C" and its name won't be mangled, and it will be accessible from C, and it will be itself able to use C++ features:
extern "C" void Foo()
{
std::string hello = "Hello world!";
std::cout << hello << std::endl;
}
You will then need to declare it on the C side of your program like this:
void Foo();
And you'll be able to call it.
It's possible for you to wrap all your C++ calls that you want to expose to your C program in extern "C" functions, and return a pointer to your type and deal with it that way, but it's going to get annoying very quickly. You really should just use C++.
As far as linking with the static library is concerned, in Xcode, go to your project settings, pick your target, go to the Build Phases tab, unfold the "Link Binary With Libraries" section, and drop your .a file there.
I have a program written in C and I need to use KDIS libraries which are written in C++. I compile my C program with automake&friends in KDevelop. How can I compile everything together?? Because I want to call some KDIS functions inside my C program.
Thank you in advance.
If you need to call C++ functions which are not declated extern "C", then you have to do so from a C++ program yourself. You can create one single C++ file in your project which wraps all the library functions you need in extern "C" functions to be used by the rest of your project. You'll have to tell autotools that you're using both C and C++. The file extensions should be enough to decide which is which.
To give you an example, consider the following mymagic.cc creating bindings for some libmagic written in C++:
#include <libmagic/magic.hh>
extern "C" {
int doMagic() {
magic::Wizard w("foo", 42);
magic::Result res = w.doMagic();
return res.getResultCode();
}
}
To the rest of your application, doMagic() would appear as just another C function. But the inside is C++, so it can use any C++ constructs you want. When you need to pass stuff from your library around, you should use pointers to opaque types. So in the header mymagic.h which is also used by your C code, you can write
struct magicValue;
int doMagic(void);
struct magicValue* createMagic(void);
void destroyMagic(struct magicValue*);
And in the mymagic.cc you'd then be more explicit:
struct magicValue {
magic::value v;
magicValue(magic::value val) : v(val) { }
};
magicValue* createMagic() {
return new magicValue(magic::value("foo"));
}
void destroyMagic(magicValue*) {
delete magicValue;
}
This link may help you understand how to mix C and C++ code in your application.
Also, look at this Stack Overflow question, I believe that's what you need.
A few days back, I came across this piece of C++ code, though I can't paste the code itself, I could recreate the problem with some sample code.
First, the file, namespace.h:
#include <iostream>
using namespace std;
namespace useless{
class X {
int m_myint;
static X *m_foobar;
X* getPrivVal(void);
public:
int getMember(void);
X* getStaticVal(void);
};
}
Next, namespace.cpp:
#include "namespace.h"
extern "C"{
namespace useless{
X* X::m_foobar = NULL;
X* X::getPrivVal(void){
if(m_foobar == NULL)
m_foobar = new X;
return(m_foobar);
}
}
}
namespace useless {
int X::getMember(void){
if(m_myint == 0)
m_myint = 1;
return(m_myint);
}
X* X::getStaticVal(void){
return(getPrivVal());
}
}
using namespace useless;
int main(void){
X y;
cout << "The int value is " << y.getMember() << endl;
cout << "The value of the static member is " << y.getStaticVal() << endl;
return(0);
}
This code compiled and linked fine when I used g++ 3.4.3, but gives the following error when I use g++ 4.x, I have tried with GCC 4.6.1 as well GCC 4.2.1. Have tried it on Linux as well as Mac, same results.
This is the error(Suse):
g++ -o namespace namespace.cpp
namespace.h:8:15: error: previous declaration of useless::X*
useless::X::m_foobar with C++ linkage
namespace.cpp:5:11: error: conflicts with new declaration with C linkage
Can someone please shed some light on what the legacy C++ code was looking to do, could this have been a hack or workaround to get around an old problem that I am not aware of any longer. Ohh by the way, the method inside the extern "C" is called by C++ code and not any C code as I initially suspected.
FYI, this is legacy code now, may have been written in 2001/2002 period.
Thanks guys. I have gone ahead and got rid of the extern "C" with no major impact.
#Bjorn Pollex : The guy who wrote that code is long gone.
The extern "C" directive has two effects, it disables mangling when possible and uses the C calling convention. In this particular case, because there is a namespace in between, name mangling cannot be disabled, so it could have been added to force a particular calling convention.
The code is actually wrong in that the declaration does not force extern "C" but the definition does, which is incorrect. Consider that if the compiler just followed the directive as shown, the caller would use C++ naming and calling conventions, while the function would be using the C variant, if the two differ the result will be undefined behavior.
Seems like an attempt to generate the variables witout C++ name mangling. That's one part of using extern "C".
The newer compiler obviously realizes that it really doesn't work.
If you have a piece of C++ code that you want to call from a module written in another language (C, FORTRAN or whatever), you want to turn off C++ name mangling.
Edit:
The really weird thing is that they did it on the definition but not on the declaration. It's a wonder that it ever compiled