Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exposing only void pointers in an API

Tags:

c

void

api

I've seen a good deal of C libraries that do not present the objects they deal with internally as distinct types, but instead wrap them with void pointers before letting you access them. In practice, the "private" source files look something like:

typedef struct {
    int value;
} object;

void * object_new(void)
{
    object *o = malloc(sizeof(object));
    o->value = 1;
    return o;
}

int object_get(void *o)
{
    return (object *)o->value;
}

void * object_free(void *o)
{
    free(o);
}

And in the main header you have only:

void * object_new(void);
int object_get(void *o);
void * object_free(void *o);

Now I wonder: is there a particular reason they do so? If the idea is to ensure the API user has no access to the internals of the object, isn't it sufficient to only expose the type name in the main library header, and to hide the details of the underlying structure (or whatever be the actual object) in the implementation files?

like image 687
michaelmeyer Avatar asked Feb 13 '14 00:02

michaelmeyer


People also ask

What is one reason you would use a void pointer?

Why do we use a void pointer in C programs? We use the void pointers to overcome the issue of assigning separate values to different data types in a program. The pointer to void can be used in generic functions in C because it is capable of pointing to any data type.

What is the limitation of void pointer?

The only limitations with void pointers are: you cannot dereference void pointer for obvious reasons. sizeof(void) is illegal. you cannot perform pointer arithmetics on void pointers.

Can void pointers point to anything?

A void pointer is a pointer that can point to any type of object, but does not know what type of object it points to. A void pointer must be explicitly cast into another type of pointer to perform indirection. A null pointer is a pointer that does not point to an address. A void pointer can be a null pointer.

What we Cannot do on a void pointer?

Because the void pointer is used to cast the variables only, So pointer arithmetic can't be done in a void pointer.


1 Answers

The reason to hide the types behind void pointers could be a (misguided) attempt to hide (in the sense of modular programming) the internal details. This is dangerous, as it throws any type checking the compiler might do right out the window.

Better would be something along the lines:

for-user.h:

struct internalstuff;
void somefunc(struct internalstuff *p);

for-internal-use.h:

#include "for-user.h"

struct internalstuff { ...};

implementation.c:

#include "for-internal-use.h";


void somefunc(struct internalstuff *p)
{
   ...
}

This way nobody will mix up internalstuff with a random string or the raw result from malloc(3) without getting at least a warning. As long as you only mention pointers to struct internalstuff in C it is fine not to have the definition of the struct at hand.

Something along the same lines can be done in C++ with class, and I'd be suprised if Objective C doesn't allow the same. But the object oriented programming languages have their own, much more flexible, tools for this. There you can define a bare-bones base class to export, while internally extensions are used. Take a look at a good C++ book for details (there are extensive lists here).

like image 144
vonbrand Avatar answered Sep 19 '22 10:09

vonbrand