Reputation: 27375
I'm designing a library and came to an issue about separating operations that are public and library private. I have the following library interface:
libmylib.h
:
typedef struct lib_context lib_context;
int init_library_context(const char **paths,
size_t path_num,
lib_context **ctx_out);
void release_context(lib_context *ctx);
For testing purpose I want to provide a function allocating memory for the opaque structure to be used in unit tests. But since clients do not need this function I decided to make it private(and put the definition of the struct in there too):
lib_context_internal.h
:
//the definition is simplified for brevity sake
struct lib_context{
size_t paths_num;
const char *path[];
};
lib_context * allocate_context(size_t paths_num);
But the definition of the functions is provided in libmylib.c
(there is no lib_context_internal.c
file):
libmylib.c
:
#include "limylib.h"
#include "lib_context_internal.h"
lib_context * allocate_context(size_t paths_num){
size_t size = sizeof(struct lib_context) + sizeof(const char *[paths_num]);
return calloc(1, size);
}
void release_context(lib_context *ctx){
//release all strings in the lib_ctx
free(ctx);
}
int init_library_context(const char **paths,
size_t path_num,
lib_context **ctx_out){
//open sockets, init epoll, etc...
*ctx_out = allocate_context(paths_num);
return 0;
}
The thing that bothers me is that I put allocation/deallocation function related to the same data structure in different headers (even though) I defined them in the same .c
file. Isn't it common to do things like that?
Upvotes: 1
Views: 76
Reputation: 223689
Having a separate header like this is fine. If it happens that other implementation files in your library need access to the types or functions defined there then they can include that header as well. As long as that internal header is not distributed with the compiled library, you're fine.
The one thing I would do is include the public header in the private header. That way the implementation files only need to worry about including the private header.
lib_context_internal.h:
#include "limylib.h"
//the definition is simplified for brevity sake
struct lib_context{
size_t paths_num;
const char *path[];
};
lib_context * allocate_context(size_t paths_num);
libmylib.c:
#include "lib_context_internal.h"
lib_context * allocate_context(size_t paths_num){
size_t size = sizeof(struct lib_context) + sizeof(const char *[paths_num]);
return calloc(1, size);
}
...
Upvotes: 4