Question

api.h

The following API is assumed to be distributed as a shared library.

#include "apiInternal.h"

internalStruct* API_init();
extern void API_set_member1(internalStruct* apiStruct, int value);
extern void API_set_member2(internalStruct* apiStruct, int value);

apiInternal.h

typedef struct internalStruct {
    int member1;
    int member2;
} internalStruct;

sample.c

The program sample.c uses api.h and links with the shared library to use the API. #include "api.h"

int main()
{
    internalStruct *myVar = API_init();
    API_set_member1(myVar, 5);
    API_set_member2(myVar, 6);
}

The dilemma here is,

  1. Should the api.h that the API implementation uses be different than the api.h distributed to the users of the API? If so, how can I do this without including apiInternal.h?
  2. Is there a better way to do/design this?
Was it helpful?

Solution

You can build sample.c without including apiInternal.h and the structure definition.

Within api.h drop the #include "apiInternal.h". Instead, declare the structure, this is called a forward declaration, (easiest to drop the typdef) so api.h will look like:

struct internalStruct;

struct internalStruct* API_init();
extern void API_set_member1(struct internalStruct* apiStruct, int value);
extern void API_set_member2(struct internalStruct* apiStruct, int value);

This works because the compiler can build sample.c as it only needs to know the size of the pointer rather than the complete structure declaration. You then only need to include apiInternal.h within your library code. You won't need to distribute apiInternal.h to your users.

If you library code has multiple files, then you will need apiInternalh.h. Each of you library source files will include apiInternal.h. If you library code is a single file, then I typically just define the structure at the top of the library C file, the extra header is not necessary.

This is called an opaque pointer. The Wikipedia article provides an additional example. This is nice way of achieving information-hiding from within C.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top