3

これの重複がないかSOをチェックしましたが、問題の正確な解決策を見つけることができませんでした。

NvCommon.h列挙型を使用するヘッダーファイルがありますNV_DATA_TYPENvDefs.hこの列挙型は、からのいくつかの構造体と列挙型を使用する別のヘッダーで定義されていNvCommon.hます。循環依存のため、これを構築できません。forwrdが列挙型を宣言することは不可能であることを私は知っています。

この状況で何ができるでしょうか?これは私のデザインの問題ですか?これを解決するために別のヘッダーファイルを導入する必要がありますか?

私はCの専門家ではありません。私を助けてください。私のデザインには問題がある可能性があり、別のヘッダーファイルを導入することでこの循環依存関係を修正できることがわかっています。私が知りたいのは「それが唯一の道」です。可能な場合は代替ソリューションを探しています。

役に立ったら、完全なコードを投稿します。

4

5 に答える 5

10

独自のファイルで列挙型を定義すると便利な場合があります。ここで定義すると、問題は解消されます。

于 2013-02-19T13:18:37.537 に答える
6

私があなたの質問を正しく理解しているなら、あなたはこのようなものを持っています:

derpfoo.h:

#ifndef DERPFOO_H
#define DERPFOO_H

#include "derpbar.h"

typedef struct {
        char *nothing;
} FOO;

BAR foo (BAR derp) {
        return derp;
}

#endif

derpbar.h:

#ifndef DERPBAR_H
#define DERPBAR_H

#include "derpfoo.h"

typedef struct {
        char *nothing;
} BAR;

FOO bar (FOO derp) {
        return derp;
}

#endif

次に、単純なderp.c:

#include "derpfoo.h"
#include "derpbar.h"

int main (void) {
        return 0;
}

私の友人は、しばらく前にいくつかのSDLコードでこの問題を提示しましたが、彼がやっていることをなぜやっているのか、そしてそれを合理的に修正する方法の両方を理解するのに時間がかかりました。

このようにコードを分離する目的は、derpfooとderpbarが論理的に分離されていることですが、残念ながら、これらは相互に依存しています。そのようなことに対して私が見つけた最も簡単な解決策は、それらを組み合わせて、そのような論理ではなく、解剖学的構造に従ってそれらを分割することです:

derpstructs.h:

#ifndef DERPSTRUCTS_H
#define DERPSTRUCTS_H

typedef struct {
        char *nothing;
} FOO;

typedef struct {
        char *nothing;
} BAR;

#include "derpfunctions.h"

#endif

derpfunctions.h:

#ifndef DERPFUNCTIONS_H
#define DERPFUNCTIONS_H

#include "derpstructs.h"

BAR foo (BAR derp) {
        return derp;
}

FOO bar (FOO derp) {
        return derp;
}

#endif

それでも単純なderp.c:

#include "derpstructs.h"
#include "derpfunctions.h"

int main (void) {
        return 0;
}

derpstructs.hには、最初ではなく最後にderpfunctions.hが含まれていることに注意してください。これは厳密に言えば必要ではありませんが、相互に含める場合は、依存する構造体定義の後に、可能なすべての包含パスに関数定義を含める必要があります。先に進む...

このソリューションは機能しますが、問題の原因となった元の哲学に正確に準拠しているわけではありません。つまり、2つの部分は論理的に分離されているため、コード内でそのように維持する必要があります。

両方の答えは、すべてをさらに分割し、包含パスをさらに微調整することです。

derpfoostructs.hには、最初にderpbarstructs.hが含まれ、次にstruct FOOが定義され、最後にオプションでderpfoofunctions.hとderpbarfunctions.hが含まれます。

derpbarstructs.hには、最初にderpfoostructs.hが含まれ、次にstruct BARが定義され、最後にオプションでderpfoofunctions.hとderpbarfunctions.hが含まれます。

derpfoofunctions.hには、最初にderpfoostructs.hとderpbarstructs.hが含まれ、次にderpbarfunctions.hが含まれ、次にその関数が定義されます。

derpbarfunctions.hには、最初にderpfoostructs.hとderpbarstructs.hが含まれ、次にderpfoofunctions.hが含まれ、次にその関数が定義されます。

derp.cにはderpfoostructs.hとderpbarstructs.hが含まれ、次にderpfoofunctions.hとderpbarfunctions.hが含まれ、その後、必要なことは何でも実行します。

これは、必要な要件の両方を満たします。循環依存関係を排除し、2つの論理的に分離されたコードユニットの論理的な分離を維持します。プロジェクト間で変更するときに編集するファイルは1つではなく、2つになりますが、少なくとも、変更可能なコードは不変のコードとは別に保持されます。それ、そしてそれは私が見つけた唯一の解決策です。

これがお役に立てば幸いです。あなたのプロジェクトに頑張ってください。

于 2013-02-27T09:24:02.367 に答える
2

循環依存は、インターフェースを過剰に設計していることを意味する場合があります。両方のファイルをNv.hにマージします。これで問題が簡単に解決する場合は、インターフェイスを誤って設計していたことを意味します。

于 2013-02-26T03:50:18.603 に答える
1

これをチェックしてください

変数、ライブラリ、関数などを適切に宣言および定義する方法。これは関連している可能性があります。

于 2013-02-26T21:30:52.510 に答える
1

私はあなたの説明に基づいてこの問題をモデル化してみました。私の実装では、(1)NvDefs.hでNV_DATA_TYPEを宣言するが定義しない、(2)NvDefs.hでNV_DATA_TYPEを宣言して定義する、(3)NvDefs.hでNV_DATA_TYPEを定義するが、NvCommon.hを宣言するという3つのことをテストしました。 。また、あなたの説明が提供したように、私はNvCommon.hでいくつかの構造体を作成し、NvDefs.hでそれらのオブジェクトにアクセスしました。いずれの場合も(ヘッダーファイルにガードがある場合とない場合)、コードはコンパイルされて実行され、正しい結果が得られます。

循環依存関係がNV_DATA_TYPE列挙型以外のヘッダーファイルのどこかにある可能性はありますか?

于 2013-02-27T04:42:01.200 に答える