3

本題に入る場合は、最後の 2 段落までスキップしてください。私の苦境とそれを解決するために私が取った手順に興味がある場合は、以下を読み続けてください.

現在、インターンシップの一環として C ライブラリの一部を開発しています。当然のことながら、コードにはユーザーがアクセスできない部分とアクセスできる部分があります。私は基本的に、いくつかのアーキテクチャに最適化された乱数ジェネレーター (RNG) (一様、ガウス、および指数分散数) を開発しています。後者の 2 つの RNG は、別のカーネル (プロジェクト) にあるユニフォーム ジェネレーターに依存しています。したがって、ユーザーが複数の RNG を使用したい場合は、メモリに制約があるため、コードを不必要に複製しないようにしたいと考えています (同じ関数を同じ関数を異なるアドレスで複数回定義しても意味がありません)。コード セグメント)。

ここで問題が発生します。ライブラリ内の他のすべてのカーネルの規則は、2 つのヘッダー ファイルと 2 つの C ファイル (自然な C 実装と最適化された C バージョン (いくつかの組み込み関数とアセンブリを使用し、および/またはいくつかの制限がある場合があります) にそれぞれ 1 つ) があることです。これに続いて、メイン関数が配置された別の C ファイル (テストベンチ) が続き、両方の実装をテストして結果を比較します. とは言っても、追加のヘッダー ファイルを実際に追加することはできません。プライベートまたは保護されたアイテムも、これらすべてのジェネレーターにグローバル ヘッダー ファイルを追加することもできません。

この制限に対処するために、各 C ファイルの先頭にある#defineではなく、均一な RNG に依存する C ファイルでextern関数とextern const intを使用して、コードの移植性を高め、簡単に変更できるようにしました。一箇所。これはほとんどの場合うまくいきました。

ただし、注意が必要なのは、これらのカーネル内で内部型を使用していることです (これはユーザーに表示されるべきではなく、ヘッダー ファイルに配置されるべきではありません)。繰り返しになりますが、移植性のために、このtypedefの定義を複数のカーネルの複数の場所ではなく、1 つの場所で変更できるようにしたいと考えています。これは、ライブラリが後で別のプラットフォームで使用される可能性があり、アルゴリズムが機能することが重要であるためです。 32ビット型を使用しています。

したがって、基本的に、Cでtypedefを「保護」する方法があるかどうか疑問に思っています。つまり、それを必要とするすべてのCファイル間で表示される必要がありますが、ユーザーには表示されません。ヘッダー ファイルの 1 つに含めることができますが、プロジェクトにそのヘッダー ファイルを含めるユーザーには、それが何であれ、見えてはなりません。

============================編集===================== ===========
また、使用している typedef が unsigned int であることにも注意する必要があります。それで

typedef unsigned int myType

構造は関係ありません。

============================スーパーエディット==================== ======
stdint.h の使用も禁止されています :(

4

2 に答える 2

2

やるだけ

typedef struct foo foo;

これらは、a の前方宣言とstruct同じ名前の型エイリアスの 2 つの宣言です。前方宣言structは、それらへのポインターを定義する以外に使用できません。これにより、十分な抽象化と型の安全性が得られます。

あなたが持っているすべてのインターフェースで

extern void proc(foo* a);

関数を提供する必要があります

extern foo* foo_alloc(size_t n);
extern void foo_free(foo* a);

これにより、ユーザーとライブラリが常に同じを使用するようにバインドされますstruct。これにより、 の実装はfooAPI ユーザーには完全に隠されます。ユーザーはキーワードなしstructで使用する必要があるため、いつか a 以外のものを使用することを決定することさえできます。foostruct

編集:typedefこれらは型のエイリアスにすぎないため、ある種の整数だけではあまり役に立ちません。エイリアス化されたすべてのタイプunsignedは、交換可能に使用できます。これを回避する 1 つの方法は、それらを 内にカプセル化することstructです。これにより、内部コードが少し見苦しくなりますが、生成されたオブジェクト コードは、最新の優れたコンパイラとまったく同じになるはずです。

于 2013-07-11T21:55:43.007 に答える