C 中的不透明(抽象)数据类型

发布于 2024-08-16 23:06:17 字数 902 浏览 4 评论 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

文件 func.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

如果我在 main.c 中包含 core.h 这个错误不会不会出现,因为 try 是在 core.h 中定义的。但我希望将结构 try 隐藏到 main.c 中 - 它不应该知道 try 结构的成员。我缺少什么?

File api.h

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

struct trytag;
typedef struct trytag try;

void trial (try *);

#endif

File core.h

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

File func.c

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

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

File 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);
}

When I compile, I get:

main.c:5: error: storage size of ‘s_tryvar’ isn’t known

If I include core.h in main.c this error doesn't come as try is defined in core.h. But I want the structure try to be hidden to main.c — it should not know the members of try structure. What am I missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

深居我梦 2024-08-23 23:06:17

我认为你想做的事情是不可能的。编译器需要知道 try 结构有多大才能编译 main.c。如果您确实希望它是不透明的,请创建一个通用指针类型,而不是直接在 main() 中声明变量,而是创建 alloc_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

core.h:

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

func.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;
}

main.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);
}

I don't think what you're trying to do is possible. The compiler needs to know how big a try structure is to compile main.c. If you really want it to be opaque, make a generic pointer type, and instead of declaring the variable directly in main(), make alloc_try() and free_try() functions to handle the creation and deletion.

Something like this:

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

core.h:

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

func.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;
}

main.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);
}
梦中楼上月下 2024-08-23 23:06:17

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

Think how the opaque FILE structure works in C. You only work with pointers, and you need a function like fopen() to create an instance, and a function like fclose() to dispose of it.

那小子欠揍 2024-08-23 23:06:17

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

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

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

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

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

The problem is in main.c, the compiler hasn't seen the definition of struct try. Because of that, the compiler is limited to using pointers to struct try.

What you want to do is add two new functions to your API:

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

These functions will call malloc and free respectively.

If you don't want to limit your structure to only being allowed on the heap, you are going to have to give up on making it opaque.

提笔落墨 2024-08-23 23:06:17

有一种方法可以做一些技术上不完全是您所要求的事情,但应该达到相同的目的,即在支持非堆分配的同时保持结构不透明。

在 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);
    ...
}

There is a way to do something that technically is not exactly what you are asking for, but should serve the same purpose of keeping your structure opaque while supporting non-heap allocation.

in api.h, you state an opaque structure as follows:

struct trytag_opaque
{
    char data[sizeof(int)*2];
};

if you wanted to be more opaque than that, you could calculate the maximum size of the structure required across any supported platform, and use:

struct trytag_opaque
{
    char data[MAX_TRYTAG_SIZE];
};

Then your api.h function declarations would look like:

int try_a(struct trytag_opaque *t)

and your function code would look like:

int try_a(struct trytag_opaque *t_opaque) {
    trytag *t = (trytag *)t_opaque;
    ...
}

and your main.c would look like:

#include "api.h"
int main() {
    struct trytag_opaque t;
    ...
    try_a(&t);
    ...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文