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

このエラーに含めるcore.hmain.c、tryがで定義されているため発生しませんcore.h。しかし、私は構造tryを隠したいのですmain.c—構造のメンバーを知っているべきではありませんtry。私は何が欠けていますか?

4

4 に答える 4

7

あなたがやろうとしていることは不可能だと思います。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);
}
于 2010-01-04T19:45:20.990 に答える
1

問題は main.c にあり、コンパイラは の定義を認識していませんstruct try。そのため、コンパイラは へのポインタの使用に制限されていますstruct try

やりたいことは、API に 2 つの新しい関数を追加することです。

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

これらの関数は、それぞれ malloc と free を呼び出します。

構造をヒープ上でのみ許可されるように制限したくない場合は、構造を不透明にすることをあきらめる必要があります。

于 2010-01-04T19:52:31.520 に答える
1

不透明な FILE 構造が C でどのように機能するかを考えてみてください。ポインターのみを操作し、インスタンスを作成するには fopen() のような関数が必要で、インスタンスを破棄するには fclose() のような関数が必要です。

于 2010-01-04T19:47:32.653 に答える
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 に答える