In order to keep the contents "opaque" to external users, bplib externally uses a "bp_desc_t" object which is nothing more than a wrapped pointer to the real object, which is internally a void*.
While this does accomplish the goal of keeping the channel definition internal/private to bplib, this requires allocating two objects - the actual channel, and the descriptor which points to that channel, as well as requiring double-dereferencing and double-checking for NULL on all API entry points (because either the external or internal pointer could be bad).
This can all be simplified by declaring bp_desc_t as an abstract struct in the external header, while defining it concretely in the bplib.c source file. This way, it does not need to allocate two objects, and it does not need to check two pointers - just one.
In order to keep the contents "opaque" to external users, bplib externally uses a "bp_desc_t" object which is nothing more than a wrapped pointer to the real object, which is internally a
void*
.While this does accomplish the goal of keeping the channel definition internal/private to bplib, this requires allocating two objects - the actual channel, and the descriptor which points to that channel, as well as requiring double-dereferencing and double-checking for NULL on all API entry points (because either the external or internal pointer could be bad).
This can all be simplified by declaring
bp_desc_t
as an abstract struct in the external header, while defining it concretely in thebplib.c
source file. This way, it does not need to allocate two objects, and it does not need to check two pointers - just one.