Another way to accomplish the same goal(abi stability) is to use cppcomponents (www.github.com/jbandela/cppcomponents/), which is a c++11 library that does this internally while presenting you with a high-level interface where you can use all your favorite standard types (string,vector,tuple,etc) and have them work even across different compilers and standard libraries.
Wow, that seems really useful! I've been wondering for a while how to do C++ libraries best. One thing I never figured out were how to expose lists/vectors/containers, I never thought of using callbacks for that.
By the way, the restriction to a minimal subset of C++ like in this technique explains a lot of why COM is the wierd way it is. E.g. only simple types for parameters; no exceptions, instead you return HRESULTS, and so on. COM does one thing that goes beyond plain C: Interestingly, it uses the one part of the C++ ABI that is stable (whether per standard or per accident I don't know): that vtables always have a certain simple layout, and given a pointer and an interface you can predict where the virtual function pointer will sit.
I've seen a lot of tutorials in this style, but they all fall short in one major way: the user is forced to let the library take care of memory allocation.
What if I want to create and destroy the library's objects over and over using the same memory?
I'm surprised we don't see more libraries like this:
(of course, in real life the function bodies would not be inline in the header.)
size_t hairpoll_size() { return sizeof(Poll); }
void hairpoll_construct(void *mem, char const *person) { new (mem) Poll(person); }
void hairpoll_destruct(void *mem) { ((Poll *)mem)->Poll::~Poll(); }
void *poll_reusable = malloc(hairpoll_size());
while (a long time) {
char const *person = get_person_name();
hairpoll_construct(poll_reusable, person);
// use the hairpoll
hairpoll_destruct(poll_reusable);
}
free(poll_reusable);
Yeah, it's complex and it loses type safety, but if you're already wrapping in a client-side C++ library that will be hidden from the user.
There's actually a few other alternatives if you want to interop with straight-up C++ interfaces:
1. Use SWIG [1] to generate the C-API from the C++ headers (you are limited to a subset of C++: no STL, no templates, all interfaces must be pure-virtual).
2. The guys behind Mono created an amazing tool [2] that allowed you to call C++ symbols directly from managed C# code via transparent translation of the underlying ABI scheme (automatically maps the object layout, vtable layout, and name mangling scheme and emits code at runtime). They finished the GCC ABI and added partial support for MSVC ABI. Sadly the project seems to be abandoned in recent months.
If interested, take a look at my slides are at https://github.com/boostcon/cppnow_presentations_2014/blob/m...
and my C++Now talk at http://www.youtube.com/watch?v=a4iFJuNBx7U&list=UU5e__RG9K3c...