假设以下API作为共享库分发。
#include "apiInternal.h"
internalStruct* API_init();
extern void API_set_member1(internalStruct* apiStruct, int value);
extern void API_set_member2(internalStruct* apiStruct, int value);
typedef struct internalStruct {
int member1;
int member2;
} internalStruct;
程序sample.c
使用api.h
并与共享库链接以使用API。
#include“api.h”
int main()
{
internalStruct *myVar = API_init();
API_set_member1(myVar, 5);
API_set_member2(myVar, 6);
}
这里的困境是,
api.h
应该不同于
api.h
分发给API的用户?如果是这样,我该怎么办
这不包括apiInternal.h
?答案 0 :(得分:1)
您可以在不包含sample.c
和结构定义的情况下构建apiInternal.h
。
在api.h
内删除#include "apiInternal.h"
。相反,声明结构,这被称为前向声明,(最容易丢弃typdef)所以api.h
将如下所示:
struct internalStruct;
struct internalStruct* API_init();
extern void API_set_member1(struct internalStruct* apiStruct, int value);
extern void API_set_member2(struct internalStruct* apiStruct, int value);
这是有效的,因为编译器可以构建sample.c
,因为它只需要知道指针的大小而不是完整的结构声明。然后,您只需要在库代码中包含apiInternal.h
。您无需向用户分发apiInternal.h
。
如果您的库代码有多个文件,那么您将需要apiInternalh.h
。每个库源文件都包含apiInternal.h
。如果库代码是单个文件,那么我通常只在库C文件的顶部定义结构,不需要额外的头。
这称为opaque pointer
。 Wikipedia article提供了另一个示例。这是从C中实现信息隐藏的好方法。