Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct typedef for an opaque C pointer to a C++ class?

Tags:

c++

c

typedef

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

  • Which form is the best?
  • Which guarantees does it provide over void*?
  • How does it work?
like image 235
Pepijn Avatar asked Jul 22 '18 08:07

Pepijn


People also ask

What is an opaque pointer in C?

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.

Why use typedefs?

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.

What is typedef in C++ with example?

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.

What is Opaquepointer in Swift?

Opaque pointers are used to represent C pointers to types that cannot be represented in Swift, such as incomplete struct types.


1 Answers

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.

like image 120
Yakk - Adam Nevraumont Avatar answered Sep 28 '22 03:09

Yakk - Adam Nevraumont