2012-05-10 9 views
0

私が直面している問題の種類に近づく標準的な方法があるかどうか疑問に思っていました:ライブラリ作成:標準的なソリューションですか?

私はCでライブラリを書いています.Liは配列を満たす関数特定のタイプのデータを使用したり、それらのデータを使用して計算したりすることができます。

libは特定の問題の解決に役立つはずなので、最初に作成したデータを後で計算に使うことが期待されます。

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

私の考えは次のとおりです。

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

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

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

答えて

6

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

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

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

  1. FOO handle = foo_init (...); - あなたはあなたの問題に固有のhandleを得ます。 FOOは通常、解決したい問題の特定の「インスタンス」に固有の情報であるすべてを含む不透明な構造体へのポインタです。すべてライブラリによって提供される関数はFOO handleパラメータを取るため、彼らは彼らがどのような問題のインスタンスを処理しているかを知る。 initが失敗すると、NULLが返されます。

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

  3. errorcode = foo_execute (handle); - ソリューションを実行します。

  4. 別のライブラリ関数を呼び出すことによって解決策を読みたいことがあります。ここでも、handleがパラメータです。

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

1

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

staticを使用すると非常に制限されると感じます。

これはちょうど私の意見ですが

2

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

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

を定義します(のみ示されたプロトタイプ)このタイプに便利な機能の束を追加します。

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

参照パイクのNotes on Programming in C、ルール5複雑さの:データが支配

関連する問題