2

私は 2 つの異なるもののチェックサムを取る関数を書いています。1 つはファイルです。もう 1 つは、BSD libarchiveライブラリのようなアーカイブ エントリです。GNU の coreutils からチェックサム コードを借りました。

ファイルのチェックサムを実行するための私のコードは、次のようにソースから読み取ります。

unsigned char buf[BUFLEN];
size_t bytes_read;
FILE *fp;
...
while ((bytes_read = fread (buf, 1, BUFLEN, fp)) > 0) { ... }

アーカイブ エントリから読み取るコードでは、対応するコードは次のようになります。

struct archive *ar;
unsigned char buf[BUFLEN];
ssize_t bytes_read;
...
while ((bytes_read = archive_read_data(ar, buf, sizeof(buf))) > 0) { ... }

現状では、コードの大部分は同じですが、ここでは 2 つの異なる関数を用意する必要があります。fread と archive_read_data には同じ数の引数さえないため、関数ポインターを渡すことによってそれを行う方法がよくわかりません。(fread(3) の代わりに read(2) を使用して開始できると思いますが、それが生産的な方法であるかどうかはわかりません。)

ここでコードの重複を避ける良い方法はありますか? 関数ポインタを使ってそれをやろうとする以外に、同じコードの断片を別々のファイルに入れてから #including'ing' することでそれを行うことができましたが、それは醜いようです。

この特定の例では、関数のコードはそれほど長くないため、先に進んでコードを複製することはそれほど大したことではありません。エレガントなソリューションが存在するかどうか疑問に思っています。

4

3 に答える 3

2

同一のプロトタイプを持つ とfread()の独自のラッパー関数を作成できます。archive_read_data()これらの各ラッパーには、read()必要に応じてパラメーターを再配置して、基になる関数を呼び出すためのコードが 1 行だけ含まれます。

次に、関数ポインターを使用して、コンテキストに応じて 2 つのラッパーを区別します。

于 2012-04-10T20:42:41.607 に答える
1

チェックサムを分析するコードが同じであれば、それを関数にすることができます - それは中括弧内の部分です。私の意見では、同じ関数を呼び出す場合、2 つの別々のループを持つことはそれほど悪くはありません。それらは薄いラッパーと見なすことができます。

于 2012-04-10T20:48:27.553 に答える
0

どちらの関数も、実際には 3 つの引数しか必要としません。

  • データ ソースへのポインタ
  • データ バッファへのポインタ
  • 読み取るバイト数

freadと同じ署名を与えるためのラッパー関数を書くことができますarchive_read_data(またはその逆):

ssize_t my_fread(FILE *fp, char *buf, int len) {
  return fread(buf, 1, len, fp);
}
于 2012-04-10T20:43:57.597 に答える