You are almost there. Your interface should be in the form of pointers to an opaque type:
struct hidden_implementation_type; typedef struct hidden_implementation_type visible_type_to_clients; int component_function1(visible_type_to_clients *instance_type);
and
int main(void) { visible_type_to_clients *a = 0; return component_function1(a); }
It will at least be compiled - but nothing useful will be. You will probably need a function, for example:
visible_type_to_clients *new_visible(void);
to create a type value and return a pointer, and then you can use:
int main(void) { visible_type_to_clients *a = new_visible(); return component_function1(a); }
Basically, clients will not be able to create structures on the stack (or global structures) of your type, because you did not tell the compiler how large this type is. But you can deal with pointers - and typed pointers are much safer than untyped void * pointers.
I have lost error checking for simplicity. I delete the name of the structure tag without the main underscore, because for all practical purposes, names starting with the underscore are reserved for implementation . I would go with:
typedef struct VisibleType VisibleType;
where the tag and type name match.
Jonathan leffler
source share