【问题标题】:Opaque struct that has some private operations具有一些私有操作的不透明结构
【发布时间】:2019-04-01 17:12:49
【问题描述】:

我正在设计一个库,遇到了一个关于分离公共操作和库私有操作的问题。我有以下库接口:

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 文件中定义了它们。这样做不是很常见吗?

【问题讨论】:

  • 为什么不给客户端分配分配功能?允许客户端通过其他方式分配内存将是一个很好的设计。
  • @SergeyA 我想到了这一点,但是我必须将指针传递给分配的struct lib_context 并初始化init_library_context 中的结构。结果证明很容易出错,因为定义包含灵活的数组成员,因此调用者可能会出错并超出范围......

标签: c software-design opaque-pointers


【解决方案1】:

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

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

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

...

【讨论】:

    猜你喜欢
    • 2016-12-26
    • 1970-01-01
    • 2019-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多