我正在尝试创建具有不同实现的接口定义。该接口被定义为一个 typedef 结构,其中包含一些函数指针和一个 void* 成员,该成员旨在成为指向特定于实现的结构的指针。这个想法是这个结构将保存配置数据来初始化特定的实现,并且该结构对于不同的实现是不同的。
问题在于取消引用内部结构,因为编译器认为它是 void* 类型。
这是我的基本框架的简化片段:
// interface.h
typedef struct {
void* cfg;
void (*write)(int val);
}Dev;
// implementation.h
#include "interface.h"
typedef struct fooInitCfg {
int a;
int b;
}fooInitCfg;
fooInitCfg* foo_cfg();
void foo_init(Dev* self, fooInitCfg* cfg);
// implementation.c
#include "implementation.h"
// Implement foo_write() ...
Dev* foo_create() { return malloc(sizeof(Dev)); }
void foo_free(Dev* self) { free(self); }
void foo_init(Dev* self, fooInitCfg* cfg)
{
self->cfg = cfg;
self->write = foo_write;
printf("%s::%d:: Init values: %d, %d\n\r", __func__, __LINE__, self->cfg->a, self->cfg->b);
}
fooInitCfg* foo_cfg(int a, int b)
{
fooInitCfg* cfg = malloc(sizeof(fooInitCfg));
cfg->a = a;
cfg->b = b;
return cfg;
}
// main.c
Dev* f1 = foo_create();
fooInitCfg init = {5, 100};
fooInitCfg* f1_init = foo_cfg(5, 100);
foo_init(f1, f1_init);
这是我得到的编译器错误:
gcc -std=c99 -g -Wall -c foo.c -o foo.o
foo.c: In function ‘foo_init’:
foo.c:25:77: warning: dereferencing ‘void *’ pointer
25 | printf("%s::%d:: Init values: %d, %d\n\r", __func__, __LINE__, self->cfg->a, self->cfg->b);
| ^~
foo.c:25:77: error: request for member ‘a’ in something not a structure or union
我尝试了很多方法来解决这个问题,但我不太清楚如何让它发挥作用。我尝试了一个灵活的数组成员,但似乎它需要接口中的已知类型而不是 void*。
cfg 的类型需要显式给出,否则,根据类型 Dev 中的定义,GCC 编译器将其视为 (void*)。
以下代码修改后即可通过GCC编译。
printf("%s::%d:: Init values: %d, %d\n\r", __func__, __LINE__,
((fooInitCfg*)(self->cfg))->a,
((fooInitCfg*)(self->cfg))->b);
运行结果如下
foo_init::24:: Init values: 5, 100