- ベストアンサー
C言語でのLinuxとwindows共通のファイル一覧取得
C言語でファイル一覧を読み込む関数を使いたいのですが、 Linuxとwindowsで共通になるようにラッピングAPIを作りたいです。 環境はLinuxはGCC、windowsはVC++6です。 my_opendir()、my_readdir()、my_closedir()というAPIとして、 Linux側はそれぞれopendir()、readdir()、closedir()を 内部で呼べばいいですが、問題はwindowsです。 my_opendir()内部で_findfirst()を呼んでしまうと、 一個目のファイルが読まれてしまいます。 グローバル変数に読まれたデータを保存して、 my_readdir()時の最初の時に読み出す方法も考えたのですが、 これだとリエントラントになりません。 何かいい方法はないでしょうか?
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
my_opendirの返す値を構造体にして、その中にデータを保存すればいいでしょう。 struct my_opendir_data { long handle; /*_findfirstの返したハンドル*/ char *firstfile; /* _findfirstが返した最初のファイル名*/ }; struct my_opendir_data *my_findfirst(const char *dir) { (略) long handle = _findfist(filename, &fileinfo); struct my_opendir_data *data = malloc(sizeof(*data)); data.handle = handle; data.firstfile = malloc(strlen(fileinfo.name)+1); strcpy(data.firstfile, fileinfo.name); return data; } BOOL my_readdir(char *dst, struct my_opendir_data *data) { if (data->firstfile) { strcpy(dst, data->firstfile); free(data->firstfile); data->firstfile = NULL; return TRUE; } else { _findnextの呼び出し } } BOOL my_closedir(struct my_opendir_data *data) { _findclose(data->handle); free(data->firstfile); free(data); } こんな感じで。
その他の回答 (2)
- rinkun
- ベストアンサー率44% (706/1571)
ANo.1です。 > 結局、staticな変数を使うのでリエントラントにならないなぁと。 my_opendir()の返値を構造体ポインタにして構造体に必要なデータを含ませればstatic変数は必要なくなるよ。構造体はmallocで確保するか、面倒なら引数で受け取るようにしても良い。 これは一般的なリエントラント化の手法なのでちゃんと理解しておいた方が良いよ。
お礼
そうですね。 まだまだ勉強が足りないようです。 また、よろしくお願いいたします。
- rinkun
- ベストアンサー率44% (706/1571)
my_opendir()は何を返すの? opendir()から類推すると何らかの構造体へのポインタを返すでしょうから、この構造体に必要なデータを保持できるようにすれば良いでしょう。 _findfirst()の呼び出しはmy_opendir()では行わず、初めてmy_readdir()が呼び出された時点で行うことも可能だと思います。
お礼
結局、staticな変数を使うのでリエントラントにならないなぁと。 割り込み禁止にすればいい話なんですけど。 my_opendir()の返り値はあんまり考えてなかったです。 MY_DIRHANDLE型とか定義して、Linuxならdirent *でwindowsならlongとかかなぁ。 一番いいのは_findnext()で取れるファイル名を一個戻せれば一番なんですけど・・・。
補足
お礼のところで間違いが一点。 ×Linuxならdirent *でwindowsならlongとかかなぁ ○LinuxならDIR *でwindowsならlongとかかなぁ
お礼
なるほど。 構造体の中にmallocした領域のポインタを保存しておくのですね。 正直、引数をopendir()/readdir()/closedir()と合わせたいのと mallocをできるだけ使いたくなかったので、 あんまり考えないで居たのですが、 結構すっきりするものですね。 ありがとうございました。