How to mix C++ and C correctly
Here is a working example:
wrapper.h (C & C++ aware)
#ifndef WRAPPER_H_
#define WRAPPER_H_
#ifdef __cplusplus
extern "C" {
#endif
typedef struct CPPClass CPPClass;
CPPClass* CPPClass_new();
void CPPClass_do_something(CPPClass* cppclass);
int CPPClass_get_state(CPPClass* cppclass);
void CPPClass_delete(CPPClass* cppclass);
#ifdef __cplusplus
}
#endif
#endif /* WRAPPER_H_ */
wrapper.cpp (C++ only)
#include "wrapper.h"
class CPPClass
{
int state;
public:
CPPClass(): state(0) {}
void do_something() { ++state; }
int get_state() const { return state; }
};
extern "C" CPPClass* CPPClass_new()
{
return new CPPClass;
}
extern "C" void CPPClass_do_something(CPPClass* cppclass)
{
cppclass->do_something();
}
extern "C" int CPPClass_get_state(CPPClass* cppclass)
{
return cppclass->get_state();
}
extern "C" void CPPClass_delete(CPPClass* cppclass)
{
delete cppclass;
}
use-wrapper.c (C only)
#include <stdio.h>
#include "wrapper.h"
int main(void)
{
CPPClass* cppclass = CPPClass_new();
if(!cppclass)
{
printf("ERROR: failed to create CPPClass:\n");
return 1;
}
printf("state: %d\n", CPPClass_get_state(cppclass));
CPPClass_do_something(cppclass);
printf("state: %d\n", CPPClass_get_state(cppclass));
CPPClass_delete(cppclass);
}
Compile CPP
g++ -std=c++11 -shared -fPIC -o libwrapper.so wrapper.cpp
Compile C
gcc -o use-wrapper use-wrapper.c -L. -lwrapper -lstdc++
Output:
$ ./use-wrapper
state: 0
state: 1
Hope that helps.
You are creating a shared object named a.out
, then another shared object named libbindings.so
that ostensibly links to a.out
but references nothing from it. Now if a set of input files doesn't have any undefined symbols, no libraries are searched or added to the output. So libbindings.so
is essentially an empty library. Verify:
% nm a.out | grep create_foo
00000000000006bc T create_foo
% nm libbindings.so | grep create_foo
%
If you have several source files, you should build an object file from each source (use -c compilation flag), (then optionally combine the objects into a static library --- skip this step if you are not releasing static libraries) then build a shared object from previously built objects:
clang++ -c -fPIC foo.cpp
clang++ -c -fPIC bar.cpp
clang++ -shared -o libfoobar.so foo.o bar.o
If you only have one source, or very few source files you can easily compile together, you can build the shared library in one step:
clang++ -std=c++14 wrapper.cpp somethingelse.cpp -shared -fPIC -o libbindings.so
This is not recommended for large projects.