2

I'm designing a library with a public interface containing opaque struct declaration:

lib_public.h:

typedef struct lib_struct lib_struct;

void foo(lib_struct *ptr);

void bar(lib_struct *ptr);

The lib_struct opaque struct hides OS-specific implementation details so it seems to be a bad design to put it into the lib_struct.h directly. But I still want to write unit tests for it which use its members. Currently I decided to create a separate private header file containing just the struct definition:

lib_struct_linux.h:

struct lib_struct{
   int epoll;
   int acceptor_socket;
}

So the implementation lib_struct.c as well as unit test lib_struct_test.c will include this header as follows:

lib_struct.c:

#include "lib_struct_linux.h"

//function definition

lib_struct_test.c:

#include "lib_struct_linux.h"

//unit tests

The thing is such a design seems messy in the sense that the struct is defined in one private header file (lib_struct_linux.h), the functions to work with the struct are declared in another public header file (lib_public.h). And the definition of the functions in yet another implementation file (lib_struct.c).

Is it common approach? If no, how would it be possible to design it in a better way.

St.Antario
  • 26,175
  • 41
  • 130
  • 318
  • 1
    If you have an opaque structure, and the actual structure needs to be used in multiple source files in the library, then this is the best, simplest and most natural solution. To simplify it a little, so you don't need to include both the public and the private header file, only include the private header file and have the private header file include the public. – Some programmer dude Apr 05 '19 at 07:44
  • @Someprogrammerdude So in case I have more than one private headers I include the public one in all of them and use private in the implementation anywhere where it is needed. – St.Antario Apr 05 '19 at 09:32
  • 1
    Something like that yes. – Some programmer dude Apr 05 '19 at 09:37

1 Answers1

4

Yes, this is perfectly fine.

The thing is such a design seems messy in the sense that the struct is defined in one private header file (lib_struct_linux.h), the functions to work with the struct are declared in another public header file (lib_public.h). And the definition of the functions in yet another implementation file (lib_struct.c).

Allow me to reword this: "The public interface is in a public header, the implementation-only declarations are in a private header, and implementation is in a source file." Doesn't sound messy at all, in fact, it sounds like perfectly good design to me.

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455