別のcファイルで定義されている構造体にアクセスしますか?

ポインタは難しい

あるcファイルで定義されている構造体に別のcファイルからアクセスしようとしています。問題はexternキーワードを使用できず 、ヘッダーファイルで構造体を定義できないことですabstract.c内部で定義された構造体にアクセスするにはどうすればよいuse_abstract.cですか?生産性が最小限の例を次に示します。

abstract.c

#include <stdio.h>
#include <stdlib.h>

typedef struct s_strukt {
    int x;
} strukt;

strukt* create_struct() {
    strukt* s = malloc(sizeof(strukt));

    return s;
}

abstract.h

#ifndef H_ABSTRACT
#define H_ABSTRACT
struct s_strukt;

#endif

use_abstract.c

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

int main() {

    strukt *s = create_struct();
    s->x = 0;

    return 0;
}

次のコマンドを実行すると、エラーが発生しgcc use_abstract.c abstract.cます。

use_abstract.c:6:5: error: use of undeclared identifier 'strukt'; did you mean 'struct'?
    strukt *s = create_struct();
    ^~~~~~
    struct
use_abstract.c:6:5: error: declaration of anonymous struct must be a definition
use_abstract.c:6:5: warning: declaration does not declare anything [-Wmissing-declarations]
use_abstract.c:7:5: error: use of undeclared identifier 's'
    s->x = 0;
    ^
1 warning and 3 errors generated.
larsks

あなたがやろうとしていることに応じて、この特定の問題に取り組むいくつかの方法があります。

まず、コードが構造体名struct s_struktとtypedef名を混同しているようstruktです。一般に、typedefはに存在abstract.hし、クライアントコードとの実装の両方で使用できますabstract.c(一般に、タイプ名は-とは1文字異なり、同じように発音されます-と既存のCキーワードは、混乱と失望につながるでしょう)。

インターフェースと実装を明確に分離することが目標である場合は、「不透明な構造と呼ばれるものを使用できますこれは、呼び出し元のコードに定義が表示されない構造を参照する型がある場合に得られるものです(たとえば、FILEによって使用される型fopen/fclose/read/writeなど)。

ではabstract.h、次のようになります。

#ifndef H_ABSTRACT
#define H_ABSTRACT

typedef struct s_strukt strukt;

strukt *create_strukt(void);
#endif

そして、でabstract.c、あなたは持っているでしょう:

#include <stdio.h>
#include <stdlib.h>

#include "abstract.h"

struct s_strukt {
    int x;
};

strukt *create_strukt() {
    strukt *s = malloc(sizeof(strukt));
    return s;
}

上記を考えると、次のように書くことができ、use_abstract.cエラーなしでコンパイルされます。

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

int main() {
    strukt *s = create_strukt();

    return 0;
}

しかし、問題があります!struktは不透明(OPAQUE)型なので、これを実行しようとするとuse_abstract.c

s->x = 0;

それは失敗します:

use_abstract.c: In function ‘main’:
use_abstract.c:8:6: error: invalid use of incomplete typedef ‘strukt’ {aka ‘struct s_strukt’}
    8 |     s->x = 0;
      |      ^~

これに対する典型的な解決策abstract.cは、不透明な構造で値を取得/設定するためのルーチンを実装することです。たとえば、次のようにabstract.hなります。

#ifndef H_ABSTRACT
#define H_ABSTRACT

typedef struct s_strukt strukt;

strukt *create_strukt(void);
void strukt_set_x(strukt *s, int value);
int strukt_get_x(strukt *s);

#endif

そしてabstract.c、このように見えます:

#include <stdio.h>
#include <stdlib.h>

#include "abstract.h"

struct s_strukt {
    int x;
};

strukt *create_strukt() {
    strukt *s = malloc(sizeof(strukt));
    return s;
}

void strukt_set_x(strukt *s, int x) {
    s->x = x;
}

int strukt_get_x(strukt *s) {
    return s->x;
}

そして、次のuse_abstract.cように書きます。

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

int main() {
    int val;

    strukt *s = create_strukt();
    strukt_set_x(s, 0);
    val = strukt_get_x(s);
    printf("val is: %d\n", val);

    return 0;
}


しかし、不透明な構造を使用したくない場合はどうでしょうか。次に、次のように記述しますabstract.h

#ifndef H_ABSTRACT
#define H_ABSTRACT

typedef struct s_strukt {
    int x;
} strukt;

strukt *create_strukt(void);

#endif

構造体定義がabstract.hにあり、実装abstract.cとクライアントコードの両方に公開されているuse_abstract.cため、コードインuse_abstract.cは構造体メンバーに直接アクセスできるため、ゲッター/セッター関数は不要になりました上記の場合、次のようにabstract.cなります。

#include <stdio.h>
#include <stdlib.h>

#include "abstract.h"

strukt *create_strukt() {
    strukt *s = malloc(sizeof(strukt));
    return s;
}

そして、次のuse_abstract.cようになります。

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

int main() {
    strukt *s = create_strukt();
    s->x = 0;
    printf("x is: %d\n", s->x);

    return 0;
}

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

ヘッダーファイルで定義されている構造体のリストを取得します

分類Dev

その配列へのポインタを使用して、構造体の配列に含まれる構造体のフィールドにアクセスするにはどうすればよいですか?[C ++]

分類Dev

Elixirは、定義されているのと同じファイルに構造体を作成できません

分類Dev

別の.jsファイルで定義されているAngularモジュールにアクセスします

分類Dev

.ccファイルによってアクセスおよび入力されるヘッダーファイル内の構造体を宣言します

分類Dev

構造体が定義されているモジュール内の構造体にアクセスする方法[Elixir]

分類Dev

名前空間を使用するグローバル構造体を定義して、構造体を使用するファイルがこの名前空間を使用しないようにするにはどうすればよいですか?c ++

分類Dev

別のファイルのC ++クラスがコンパイルされていません。Class.objですでに定義されている1つ以上の複数定義されたシンボルが見つかりました

分類Dev

別の構造体がメンバーとして共用体にラップされている構造体が、明示的なデフォルトコンストラクターなしでコンパイルされないのはなぜですか?

分類Dev

c ++:同じ名前空間にあるが別のファイルで定義されている変数にアクセスする方法は?

分類Dev

構造体タイプの配置はCで定義されていますか?

分類Dev

別のファイルの角度ディレクティブを使用して、js ファイルで定義された変数にアクセスします

分類Dev

ヘッダーファイルで構造体を宣言し、.cファイルで定義するにはどうすればよいですか。

分類Dev

このコードを2つの.cファイルと1つの.hファイルに分割しようとしていますが、構造が他の.cファイルからアクセスされていません。

分類Dev

宣言されていない構造体にアクセスしますか?

分類Dev

別の構造体内で構造体を宣言し、プライベートとして宣言されたときに問題にアクセスする

分類Dev

mexファイルのMatlab構造体配列のデータにアクセスするにはどうすればよいですか

分類Dev

クラス内で定義された「public」構造体にアクセスします

分類Dev

サーバーがc構造体としてデータを送信しているときに、クライアントのC ++構造体にバッファーをタイプキャストできますか?

分類Dev

定義をソースファイルに隠してスタックに構造体を割り当てることは可能ですか?

分類Dev

関数に渡してCに格納されている値にアクセスするときに、構造体の構造体を効率的に使用する

分類Dev

_GNU_SOURCEを定義しても、uname構造体のドメイン名メンバーにアクセスできないのはなぜですか

分類Dev

Box <Trait>でキャストされた構造体からフィールドにアクセスします

分類Dev

.jsファイルで定義されているJavaScript関数に別の.jsファイルからアクセスできないのはなぜですか?

分類Dev

goとmongodbを使用して別の構造体の内部で定義された型構造体のスライスを取得する方法

分類Dev

ポインタとして設定された構造体の構造体メンバーにアクセスする方法は?

分類Dev

C ++のネストされたプライベート構造体タイプを考えると、ファイルスコープの静的関数からそれにアクセスするための戦術はありますか?

分類Dev

g ++で別のファイルで定義されたクラスを構築するにはどうすればよいですか?

分類Dev

Matlabの別のファイルで定義されている関数でこれらの変数にアクセスするにはどうすればよいですか?

Related 関連記事

  1. 1

    ヘッダーファイルで定義されている構造体のリストを取得します

  2. 2

    その配列へのポインタを使用して、構造体の配列に含まれる構造体のフィールドにアクセスするにはどうすればよいですか?[C ++]

  3. 3

    Elixirは、定義されているのと同じファイルに構造体を作成できません

  4. 4

    別の.jsファイルで定義されているAngularモジュールにアクセスします

  5. 5

    .ccファイルによってアクセスおよび入力されるヘッダーファイル内の構造体を宣言します

  6. 6

    構造体が定義されているモジュール内の構造体にアクセスする方法[Elixir]

  7. 7

    名前空間を使用するグローバル構造体を定義して、構造体を使用するファイルがこの名前空間を使用しないようにするにはどうすればよいですか?c ++

  8. 8

    別のファイルのC ++クラスがコンパイルされていません。Class.objですでに定義されている1つ以上の複数定義されたシンボルが見つかりました

  9. 9

    別の構造体がメンバーとして共用体にラップされている構造体が、明示的なデフォルトコンストラクターなしでコンパイルされないのはなぜですか?

  10. 10

    c ++:同じ名前空間にあるが別のファイルで定義されている変数にアクセスする方法は?

  11. 11

    構造体タイプの配置はCで定義されていますか?

  12. 12

    別のファイルの角度ディレクティブを使用して、js ファイルで定義された変数にアクセスします

  13. 13

    ヘッダーファイルで構造体を宣言し、.cファイルで定義するにはどうすればよいですか。

  14. 14

    このコードを2つの.cファイルと1つの.hファイルに分割しようとしていますが、構造が他の.cファイルからアクセスされていません。

  15. 15

    宣言されていない構造体にアクセスしますか?

  16. 16

    別の構造体内で構造体を宣言し、プライベートとして宣言されたときに問題にアクセスする

  17. 17

    mexファイルのMatlab構造体配列のデータにアクセスするにはどうすればよいですか

  18. 18

    クラス内で定義された「public」構造体にアクセスします

  19. 19

    サーバーがc構造体としてデータを送信しているときに、クライアントのC ++構造体にバッファーをタイプキャストできますか?

  20. 20

    定義をソースファイルに隠してスタックに構造体を割り当てることは可能ですか?

  21. 21

    関数に渡してCに格納されている値にアクセスするときに、構造体の構造体を効率的に使用する

  22. 22

    _GNU_SOURCEを定義しても、uname構造体のドメイン名メンバーにアクセスできないのはなぜですか

  23. 23

    Box <Trait>でキャストされた構造体からフィールドにアクセスします

  24. 24

    .jsファイルで定義されているJavaScript関数に別の.jsファイルからアクセスできないのはなぜですか?

  25. 25

    goとmongodbを使用して別の構造体の内部で定義された型構造体のスライスを取得する方法

  26. 26

    ポインタとして設定された構造体の構造体メンバーにアクセスする方法は?

  27. 27

    C ++のネストされたプライベート構造体タイプを考えると、ファイルスコープの静的関数からそれにアクセスするための戦術はありますか?

  28. 28

    g ++で別のファイルで定義されたクラスを構築するにはどうすればよいですか?

  29. 29

    Matlabの別のファイルで定義されている関数でこれらの変数にアクセスするにはどうすればよいですか?

ホットタグ

アーカイブ