There are dozens upon dozens of SO questions and blog posts that describe wrapping a C++ class with a C API. Example Wrapping C++ class API for C consumption
Most of these answers and blogposts go for something like this:
typedef void* CMyClass;
But others say that this is bad because it provides no type safety. They propose various variations of opaque structs, without any explanation. I could just copy the above snippet and move on with my life (which I will do in the meantime), but I'd like to know once and for all
void*
?In computer programming, an opaque pointer is a special case of an opaque data type, a data type declared to be a pointer to a record or data structure of some unspecified type. Opaque pointers are present in several programming languages including Ada, C, C++, D and Modula-2.
The typedef keyword allows the programmer to create new names for types such as int or, more commonly in C++, templated types--it literally stands for "type definition". Typedefs can be used both to provide more clarity to your code and to make it easier to make changes to the underlying data types that you use.
typedef keyword is used to assign a new name to any existing data-type. For example, if we want to declare some variables of type unsigned int, we have to write unsigned int in a program and it can be quite hectic for some of us.
Opaque pointers are used to represent C pointers to types that cannot be represented in Swift, such as incomplete struct types.
Use struct MyType
in C++.
Use typedef struct MyType* pMyType;
as your common handle.
Your "C" APIs should compile in both C and C++ (with extern "C"
wrappers in C++ to get correct linkage). And you'll get close to max type safety.
Now, struct MyHandle{void* private_ptr;};
is another option: this avoids exposing the name of the C++ type to C. And so long as you isolate direct interaction with private_ptr
to a handful of functions, it will be as type safe everywhere else.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With