Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C void pointers in API Design ideas

Tags:

c

I am working on a large project that is provided to our customers as a static c lib and one header file that has the prototypes for our exposed API. The project has two similar but unique builds that require different data structures to be exposed in the header. I am trying to come up with the best design to allow a single API function to work with different data structures depending on the build. This is my idea so far, but I'm worried this is a bad design.

My function will be implemented like this

void foo(void *generic_data_struct)
{
#ifdef BUILD1
   build1_t *data_struct = generic_data_struct;
#else
   build2_t *data_struct = generic_data_struct;
#endif
...
}

And the exposed API header will be, depending on the build the customer orders, either

void foo(build1_t *data_struct);

or

void foo(build2_t *data_struct);

Is this a reasonable design pattern or is this frowned upon? Thanks!

like image 423
Brandon Yates Avatar asked Dec 26 '22 18:12

Brandon Yates


1 Answers

It is almost always better to use an opaque type (struct foo;) for this kind of thing, rather than void pointers.

Whenever you have variant builds, minimizing the number of #ifdefs is highly desirable. I recommend you use eq-'s proposal, but factor out variations in function prototypes with a typedef:

/* header file */
#ifdef BUILD1
typedef build1_t generic_t;
#else
typedef build2_t generic_t;
#endif

void foo(generic_t *);
void bar(generic_t *);
/* etc */

You still need #ifdefs inside foo, bar, etc whenever actual behavior changes based on BUILD1, but you don't need them on the declaration and definition of every single function.

like image 134
zwol Avatar answered Jan 18 '23 23:01

zwol