Непрозрачная структура, которая имеет некоторые частные операции - PullRequest
1 голос
/ 01 апреля 2019

Я проектирую библиотеку и столкнулся с проблемой разделения операций, которые являются публичными и частными.У меня есть следующий интерфейс библиотеки:

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 Ответ

4 голосов
/ 01 апреля 2019

Хорошо иметь отдельный заголовок.Если случается, что другим файлам реализации в вашей библиотеке требуется доступ к определенным там типам или функциям, они также могут включать этот заголовок.Пока этот внутренний заголовок не распространяется скомпилированной библиотекой, все в порядке.

Единственное, что я хотел бы сделать, - это включить публичный заголовок в приватный заголовок.Таким образом, файлы реализации должны беспокоиться только о включении частного заголовка.

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

...
...