7

単一の静的 C プログラムに一連のデータ (たとえば、ファイルのない組み込みプラットフォームで作業しているため、実行可能ファイルに埋め込まれた画像だけでなく、他のデータも含めます) を含めたいと思います。

したがって、データファイルから const データを作成する小さな img2c を作成し、静的な const 配列初期化子を含むファイルを作成してフラッシュに配置します (C99 の優れた機能を使用)。

私の質問は、私が何度も見たように、それらを.hファイルに入れる必要があるかということです-たとえば、gimpは.cファイルではなく.hファイルとして保存できます-または.cファイルで、ヘッダーで参照されますさらに参照するための const extern 宣言。すべてのデータを含めてすべてをコンパイラに渡し、使用するたびに再宣言する必要はありません。

毎回データ全体を含めずにアドレスを参照するため、プリプロセッサ マクロは問題外です。

4

4 に答える 4

4

データをヘッダーに入れると、そのヘッダーを取得するすべてのコンパイル単位がデータの独自のコピーを取得します。それぞれが .o に移動する 2 つの .c ファイルを想像してください。各 .o にはデータのコピーがあり、最終的な実行可能ファイルは必要以上に大きくなる可能性があります。

それを .c に入れてヘッダーに extern すると、データが含まれるのは .o だけになり、最終的な実行可能ファイルは小さくなります。また、何かを変更した場合、ヘッダーを含むすべての .c ファイルではなく、単一の .c への変更だけであれば、再コンパイルが速くなる可能性があります。

ご指摘のとおり、シンボルが複数回定義されるため、リンカーで問題が発生する可能性もあります。複数の cpps に同じヘッダーを含めることによる複数定義エラーの繰り返しに対する回答を参照してください。extern をヘッダーに、データを .c に配置する方が全体的に優れています。

于 2012-08-09T13:09:18.490 に答える
3

C のヘッダー ファイルは特別なものではありません。拡張機能は、.hコンパイラがそれらを処理する方法を変更しません。「このファイルにはおそらくコードが含まれていません」という人間へのヒントです。

そのため、実際のバイナリ データをそこに入れると、コンパイラは、(単に共有グローバル配列への参照を追加するのではなく) ヘッダーをインクルードする各ファイルに配列のコピーを作成します。

GIMP は、データの使用方法がわからないため、ヘッダー ファイルを作成します。アイデアは、このヘッダー ファイルをファイルに 1 回だけ.cインクルードし、その後何らかの方法でデータを処理するというものです。ファイルを書き込んで.cコードに変更を加えた場合、データを更新するように要求すると、GIMP は変更をマージする必要があります。面倒です。

于 2012-08-09T13:11:49.597 に答える
2

これは、変数が 1 つのソース ファイルでのみ定義されていることを確認することで実行できます。このためには、ちょっとしたプリプロセッサの「プログラミング」が必要です。

ヘッダー ファイル:

/* Standard include guard */
#ifndef X_H
#define X_H

#ifdef X_SOURCE
uint8_t data[] = { /* ... */ };
#else
extern uint8_t data[];
#endif

#endif  /* End of include guard */

ソースファイル:

#define X_SOURCE
#include "x.h"

/* ... */

他のすべてのソース ファイルは、ファイルをインクルードするだけで"x.h"参照できますdata

于 2012-08-09T13:10:59.350 に答える
2

C のすべての場合と同様に、ここでのベスト プラクティスについてはいくつかの議論があります。一般的な方法は、実際の値を実装 (.c) に入れ、宣言 ( extern something something) をヘッダー (.h) に入れることです。そうすれば、ヘッダーを含むすべてのファイルを再コンパイルすることなく、値を更新できます。

答えは、「使用するたびに再宣言する」ということはほとんどありません。

于 2012-08-09T13:09:26.553 に答える