#include <stdio.h>
#ifndef API
#define API
struct trytag;
typedef struct trytag try;
void trial (try *);
#endif
#ifndef CORE
#define CORE
struct trytag
{
int a;
int b;
};
#endif
#include "api.h"
#include "core.h"
void trial (try *tryvar)
{
tryvar->a = 1;
tryvar->b = 2;
}
#include "api.h"
int main ()
{
try s_tryvar;
trial(&s_tryvar);
printf("a = %d\nb = %d\n", s_tryvar.a, s_tryvar.b);
}
当我编译时,我得到:
main.c:5: error: storage size of ‘s_tryvar’ isn’t known
如果我在core.h
中加入main.c
,则此错误不会出现,因为core.h
中定义了尝试。但我希望将结构try
隐藏到main.c
- 它不应该知道try
结构的成员。我错过了什么?
答案 0 :(得分:6)
我不认为你想做的事情是可能的。编译器需要知道编译try
的{{1}}结构有多大。如果你真的希望它是不透明的,那么创建一个通用的指针类型,而不是直接在main.c
中声明变量,使main()
和alloc_try()
函数来处理创建和删除。 / p>
这样的事情:
api.h:
free_try()
core.h:
#ifndef API
#define API
struct trytag;
typedef struct trytag try;
try *alloc_try(void);
void free_try(try *);
int try_a(try *);
int try_b(try *);
void trial (try *);
#endif
func.c:
#ifndef CORE
#define CORE
struct trytag
{
int a;
int b;
};
#endif
main.c中:
#include "api.h"
#include "core.h"
#include <stdlib.h>
try *alloc_try(void)
{
return malloc(sizeof(struct trytag));
}
void free_try(try *t)
{
free(t);
}
int try_a(try *t)
{
return t->a;
}
int try_b(try *t)
{
return t->b;
}
void trial(try *t)
{
t->a = 1;
t->b = 2;
}
答案 1 :(得分:1)
想想不透明的FILE结构如何在C中工作。你只使用指针,你需要像fopen()这样的函数来创建一个实例,并且需要像fclose()这样的函数来处理它。
答案 2 :(得分:1)
问题出在main.c中,编译器还没有看到struct try
的定义。因此,编译器仅限于使用指向struct try
的指针。
您要做的是在API中添加两个新功能:
try *create_try();
void *destroy_try(try *t);
这些函数将分别调用malloc和free。
如果您不希望将结构限制为仅允许在堆上,则您将不得不放弃使其不透明。
答案 3 :(得分:0)
有一种方法可以做一些技术上并不完全符合你要求的东西,但应该保持你的结构不透明同时支持非堆分配。
在api.h中,您声明了一个不透明的结构如下:
struct trytag_opaque
{
char data[sizeof(int)*2];
};
如果您想要更加不透明,可以计算任何支持平台所需的最大结构大小,并使用:
struct trytag_opaque
{
char data[MAX_TRYTAG_SIZE];
};
然后你的api.h函数声明如下:
int try_a(struct trytag_opaque *t)
,您的功能代码如下:
int try_a(struct trytag_opaque *t_opaque) {
trytag *t = (trytag *)t_opaque;
...
}
你的main.c看起来像是:
#include "api.h"
int main() {
struct trytag_opaque t;
...
try_a(&t);
...
}