仅在API中公开void指针

mic*_*yer 5 c api void

我已经看到很多C库没有在内部处理它们作为不同类型的对象,而是在让你访问它们之前用void指针包装它们.在实践中,"私有"源文件看起来像:

typedef struct {
    int value;
} object;

void * object_new(void)
{
    object *o = malloc(sizeof(object));
    o->value = 1;
    return o;
}

int object_get(void *o)
{
    return (object *)o->value;
}

void * object_free(void *o)
{
    free(o);
}
Run Code Online (Sandbox Code Playgroud)

在主标题中你只有:

void * object_new(void);
int object_get(void *o);
void * object_free(void *o);
Run Code Online (Sandbox Code Playgroud)

现在我想知道:他们这样做有什么特别的原因吗?如果想要确保API用户无法访问对象的内部,仅仅在主库头中公开类型名称并隐藏底层结构的详细信息(或者其他任何内容)是不够的.实际文件中的实际对象?

von*_*and 5

隐藏void指针后面的类型的原因可能是(误导)尝试隐藏(在模块化编程意义上)内部细节.这很危险,因为它抛出任何类型检查编译器可能会在窗口外执行.

更好的事情就是这样:

for-user.h:

struct internalstuff;
void somefunc(struct internalstuff *p);
Run Code Online (Sandbox Code Playgroud)

for-internal-use.h:

#include "for-user.h"

struct internalstuff { ...};
Run Code Online (Sandbox Code Playgroud)

implementation.c:

#include "for-internal-use.h";


void somefunc(struct internalstuff *p)
{
   ...
}
Run Code Online (Sandbox Code Playgroud)

这样,没有人会internalstuffmalloc(3)没有得到至少警告的情况下混淆随机字符串或原始结果.只要你只提到struct internalstuffC中的指针就可以了,没有掌握的定义struct.

可以在C++中使用相同的行来完成,class如果Objective C不允许这样做,我会感到惊讶.但面向对象编程语言有自己的,更灵活的工具.在那里,您可以定义要导出的简单基类,同时使用内部扩展.有关详细信息,请查看好的C++书籍(此处有大量列表).