具有某些私有操作的不透明结构

时间:2019-04-01 17:12:49

标签: c software-design opaque-pointers

我正在设计一个图书馆,但遇到了一个关于将公共和私有图书馆分开的问题。我有以下库界面:

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);

出于测试目的,我想提供一个函数,用于为单元测试中使用的不透明结构分配内存。但是由于客户不需要此功能,所以我决定将其设为私有(并将结构的定义也放在其中):

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);

但是功能的定义在libmylib.c中提供(没有lib_context_internal.c文件):

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;
}

困扰我的是,我将与同一数据结构相关的分配/取消分配函数放在不同的标头中(即使我在同一.c文件中定义了它们)。这样的事情不是很常见吗?

1 个答案:

答案 0 :(得分:4)

有一个像这样的单独标题是可以的。如果碰巧库中的其他实现文件需要访问在那里定义的类型或函数,那么它们也可以包含该标头。只要内部标头不随编译库一起分发,就可以了。

我要做的一件事是在私有头中包含公共头。这样,实现文件只需要担心是否包含私有标头。

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);
}

...