0

文件 api.h

#include <stdio.h>
#ifndef API
#define API

struct trytag;
typedef struct trytag try;

void trial (try *);

#endif

文件 core.h

#ifndef CORE
#define CORE
struct trytag
{
    int a;
    int b;
};
#endif

文件函数.c

#include "api.h"
#include "core.h"

void trial (try *tryvar)
{
    tryvar->a = 1;
    tryvar->b = 2;
}

文件 main.c

#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.hmain.c此错误中,则不会像 try 中定义的那样出现core.h。但我希望结构try被隐藏到main.c——它不应该知道try结构的成员。我错过了什么?

4

4 回答 4

7

我认为您尝试做的事情是不可能的。try编译器需要知道要编译的结构有多大main.c。如果你真的希望它是不透明的,那就做一个通用的指针类型,而不是直接在main()、 makealloc_try()free_try()函数中声明变量来处理创建和删除。

像这样的东西:

api.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

核心.h:

#ifndef CORE
#define CORE
struct trytag
{
    int a;
    int b;
};
#endif

函数.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;
}

主.c:

#include <stdio.h>
#include "api.h"

int main()
{
    try *s_tryvar = alloc_try();

    trial(s_tryvar);
    printf("a = %d\nb = %d\n", try_a(s_tryvar), try_b(s_tryvar));

    free_try(s_tryvar);
}
于 2010-01-04T19:45:20.990 回答
1

想想不透明的 FILE 结构在 C 中是如何工作的。您只使用指针,并且需要像 fopen() 这样的函数来创建实例,并需要像 fclose() 这样的函数来处理它。

于 2010-01-04T19:47:32.653 回答
1

问题出在 main.c 中,编译器没有看到 .c 的定义struct try。因此,编译器仅限于使用指向struct try.

您要做的是向您的 API 添加两个新函数:

try *create_try();
void *destroy_try(try *t);

这些函数将分别调用 malloc 和 free。

如果您不想将结构限制为仅允许在堆上,您将不得不放弃使其不透明。

于 2010-01-04T19:52:31.520 回答
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);
    ...
}
于 2015-11-01T05:25:30.703 回答