Лучший способ гарантировать отсутствие доступа к новым структурам кода - это не делать их доступными с помощью полной инкапсуляции.Это происходит за счет невозможности использования структуры в стеке.Вы предоставляете функцию для выделения структуры, другую для ее освобождения, и все функции модуля принимают указатель на структуру.Однако определение самой структуры находится в файле C, а не в заголовочном файле.Другим недостатком является то, что вам может потребоваться написать множество функций для управления / запроса структуры.
Я предоставлю фрагменты из старой базы кода, где я использовал этот подход.Заголовок содержит:
#ifndef INC_QUEUE_H
#define INC_QUEUE_H
typedef enum {
QUE_OK,
QUE_BAD_PARAM,
QUE_NO_MEMORY,
QUE_SYS_ERROR
} QUE_RV;
typedef struct Queue_st Queue_t;
QUE_RV QUE_New(Queue_t **ppQueue);
QUE_RV QUE_Put(Queue_t *pQueue, int priority, void *pData);
QUE_RV QUE_Get(Queue_t *pQueue, int *priority, void **ppData);
void QUE_Free(Queue_t *pQueue);
#endif /* INC_QUEUE_H */
Файл C определяет структуру Queue_st
и реализации функций (сильно модифицированных для выделения подхода):
#include "queue.h"
#include "log.h"
#define QUE_INITIAL_CAPACITY 128
struct Queue_st {
/* SNIP: structure contents go here */
};
QUE_RV QUE_New(Queue_t **ppQueue)
{
QUE_RV rv;
*ppQueue = malloc(sizeof(Queue_t));
/* SNIP: Check malloc, Initialize the structure here ... */
return QUE_OK;
}
void QUE_Free(Queue_t *pQueue)
{
if (pQueue != NULL)
{
/* SNIP: Free contents of the structure before the free below... */
free(pQueue);
}
}
Альтернативным подходом являетсяиспользовать typedef struct StructName *StructHandle;
и заменить все указатели в API на StructHandle
.На один *
меньше беспокоиться.
РЕДАКТИРОВАТЬ: Если вы хотите, чтобы некоторые члены были видимыми, а некоторые нет, это также возможно с расширением вышеуказанного подхода.В своем заголовке определите:
typedef struct StructPriv StructPriv;
typedef struct {
/* public members go here */
StructPriv *private;
} Struct;
Struct *STRUCT_Create();
void STRUCT_Free();
В файле C определите закрытые члены и функции, которые ими управляют.