C++ has excellent two-way compatibility with the C ABI, but there are some limitations you must observe to write C++ code which C code can call without marshalling at the ABI boundary:
extern "C"to prevent its symbol being mangled, and thus give it the C rather than C++ ABI.
result<T, E>or a
result<T>i.e. with the
std::error_codeor something with equal layout. Note that
std::error_codehas standard layout, and is trivially copyable, and thus is a legal type in C.
These type limitations might seem to be showstoppers to C++ programmers, but with a bit of care during library design, you can actually express a lot of complex C++ and still meet these requirements. For example, more than 80% of the APIs in my C++ 17 AFIO library (which I hope to propose in 2018 to become the File I/O TS for C++ 24) meets the above restrictions, and thus can be called directly from C code or any programming language which speaks the C ABI.
A useful tip is to sprinkle
static_assert() testing the two traits above around your header files for any types which
can traverse the C ABI boundary, and add
extern "C" free function thunks for your class
member functions1. You should be ready to go from the C++ side at least.