0

私が直面している種類の問題にアプローチする標準的な方法があるかどうか疑問に思っていました:

私はCでライブラリを書いています.libは、特定のタイプのデータで配列を埋めたり、それらのデータで計算を行ったりする関数など、さまざまな種類の関数を提供します。

ライブラリは特定の問題の解決に役立つはずなので、最初に作成されたデータが後で計算を行うために使用されることを期待するかもしれません。

したがって、問題解決プロセス全体で「共有」する必要があるデータがいくつかあります (配列のサイズや計算に役立つその他のパラメーターなど)。
これらのデータをすべての関数のパラメーターとして配置することは避けたいと思います (つまり、配列のサイズをすべての関数に渡します)。

私の考えは:

  • ライブラリ関数からのみアクセスできる一連の静的グローバル変数を作成します。

  • これらの変数のセッター/ゲッターを作成し、enum設定/取得する正確な変数をアドレス指定するために使用されるカスタム型を定義します (つまり、set(kScaleFactor, 10))。

しかし、前に述べたように、この問題に対処するための「標準的な」(または一般的に使用される) 方法はありますか? 私のアプローチは大丈夫だと考えられますか?

4

3 に答える 3

6

多くのライブラリは、問題の「インスタンス」ごとに「ハンドル」の概念を使用しています。このようにして、呼び出しが散在している場合でも、複数のハンドルを同時に開くことができ、互いの実行を混乱させることはありません。

例: C の標準入出力にはFILEハンドルがあり、libcURL にはCURLハンドルがあります。

それらを使用するときのプログラムの流れは通常このようになります[私は架空のライブラリを使用していますfoo]:

  1. FOO handle = foo_init (...);-handle問題に固有の が得られます。通常、解決したい問題の特定の「インスタンス」に固有のすべてのFOO情報を含む不透明な構造へのポインタです。ライブラリが提供する他のすべての関数はパラメーターを受け取るため、問題のどのインスタンスに取り組んでいるかがわかります。失敗すると、.FOO handleinitNULL

  2. errorcode = foo_set_option (handle, OPTION,...);- 次に、問題を解決するときにライブラリがどのように動作するかについて、いくつかの特別なオプションを設定します。これはオプションの場合があります。内部的には、これにより、 が指す構造体handleがオプションを設定するために変更される場合があります。

  3. errorcode = foo_execute (handle);- あなたは解決策を実行します。

  4. 別のライブラリ関数を呼び出して、ソリューションを「読み取る」ことができます。繰り返しhandleますが、パラメータです。

  5. foo_cleanup (handle);- 完了したら、ライブラリが割り当てた内部データ構造をクリーンアップし、占有していた他のリソースを解放します。

于 2012-05-10T10:39:37.853 に答える
2

ライブラリ設計の標準的なアプローチは、一連のデータ構造を設計し、それらに操作を実装することです。ライブラリがたとえば行列で動作する場合は、次を定義します

typedef struct {
    double *contents;
    size_t ncolumns, nrows;
} Matrix;

次に、この型に一連の便利な関数を追加します (プロトタイプのみを示します)。

Matrix *make_matrix(size_t, size_t);
Matrix *matrix_multiply(Matrix const *, Matrix const *);

Pike's Notes on Programming in Cの複雑さのルール 5:データが支配するを参照してください。

于 2012-05-10T10:23:49.967 に答える
1

オブジェクト指向のアプローチをエミュレートできます。X11 ライブラリは、typedefstovoid *ポインターを使用してこれを行います。次に、オブジェクトを最初のパラメーターとして受け取り、それをライブラリの内部データ構造にキャストして使用する関数を用意します。

static使用は非常に制限されると思います。

これは私の意見です

于 2012-05-10T10:18:11.147 に答える