4

libuvの使い方を学ぼうとしています。Mac OS Xを使用していて、ライブラリをダウンロードしてインストールしています。小さなテストプログラムをコンパイルして実行できます。1つはコールバックループを開始し、ウォッチャーがないため終了します。もう1つはアイドル状態のウォッチャーを作成し、時間がなくなると終了します。

私はファイルioのサンプルを調べようとしていて、問題が発生しています。ファイル記述子を取得する関数の関数プロトタイプは次のとおりです。

 int uv_fs_open(uv_loop_t* loop, 
                uv_fs_t* req,      // second argument
                const char* path, 
                int flags, 
                int mode, 
                uv_fs_cb cb)

サンプルコードを最小値にカットしましたが、それでもエラーが発生します。

#include <stdio.h>
#include <uv.h>

uv_fs_t open_req;

void on_open(uv_fs_t);
void on_read(uv_fs_t);
void on_write(uv_fs_t);

int main(int argc, char **argv) {

    uv_fs_open(uv_default_loop(), &open_req, argv[1], O_RDONLY, 0, on_open); 
    uv_run(uv_default_loop(), UV_RUN_DEFAULT); 
    return 0;
}


void on_open(uv_fs_t *req) {
    if (req->result != -1) {
        fprintf(stderr, "function called \n");
    }
    else {
        fprintf(stderr, "error opening file: %d\n", req->errorno);
    }
    uv_fs_req_cleanup(req);
}

私のopen_reqの宣言は、完全なコードサンプルに表示され、エラーが発生しないclose_reqの宣言とまったく同じです。コンパイラが「このスコープで「open_req」が宣言されていません」というエラーを表示したため、open_reqの宣言を追加しました。宣言を追加すると、エラーが「'void(*)(uv_fs_t)'から'void(*)(uv_fs_t *)'への無効な変換」に変更されました。宣言がmain内にあるかどうかではなく、同じエラーが発生します。宣言をポインタ宣言に変更した場合

uv_fs_t* open_req; 

次に、エラーが発生します。

cannot convert uv_fs_t** to uv_fs_t* for argument ‘2’ to 
int uv_fs_open(uv_loop_t*, uv_fs_t*, const char*, int, int, void (*)(uv_fs_t*))

私は実際のlibuvコードを調べて理解できるかどうかを確認しようとしていますが、コードは巨大です。http: //nikhilm.github.com/uvbook/にある「AnIntroductiontolibuv」を使用しています。これがサンプルコードの出所です。

このライブラリを試して理解するために使用できるサンプルコードの他のソースはありますか?私が宣言で間違っていることは明らかですか?libuvの使用方法に関する説明や例をどこで探すべきかわかりません。

更新の編集libuvコードのuv.hファイル。私は見つけます

typedef struct uv_fs_s uv_fs_t;

私がコードで探していたものの1つは、この構造体が実際に定義されている場所です。私はgoogleを使用してtypedefを検索し、typedefを使用して名前を作成する方法について少し学びました。これにより、構造体のインスタンスを宣言するたびにstructと入力する必要がなくなります。ひどい習慣だと思う人もいれば、素晴らしいと思う人もいます。close_reqと呼ばれるタイプus_fs_tの別の宣言として、最小サンプルを取得するために削除したものの一部。宣言のフォーマットをそのフォーマットから直接コピーしました。

関数へのポインタについて何がわかるかを見ていきます。私はそれらに漠然と精通しているだけで、少なくともどこかで探し始めることができます。

uv_fs_openの関数定義を見つけました。

int uv_fs_open(uv_loop_t* loop,
               uv_fs_t* req,
               const char* path,
               int flags,
               int mode,
               uv_fs_cb cb) {
  INIT(OPEN);
  PATH;
  req->flags = flags;
  req->mode = mode;
  POST;
}
4

1 に答える 1

4

関数のプロトタイプuv_fs_open

int uv_fs_open(uv_loop_t* loop, 
               uv_fs_t* req, 
               const char* path, 
               int flags, 
               int mode, 
               uv_fs_cb cb)

2番目の引数の型は。であることに注意してくださいuv_fs_t*。だからあなたopen-rec

uv_fs_t open_req;

そしてuv_fs_open()

uv_fs_open(uv_default_loop(), &open_req, argv[1], O_RDONLY, 0, on_open);

2番目の引数(&open_req)はのアドレスを取りopen_req、必要なポインタを作成します。これは問題なく機能するはずです。ただし、元のエラーメッセージから、関連するすべてのコードを投稿したわけではないと思います。このエラーメッセージを見てみましょう:

'void(*)(uv_fs_t)'から'void(*)(uv_fs_t *)'への無効な変換</ p>

これは、コンパイラーがvoidを返す関数へのポインターを予期し、へのポインターである単一のパラメーターを受け取ることを示していuv_fs_tます。一方、voidを返し、型の単一のパラメーターを受け取る関数へのポインターを提供していますuv_fs_t(つまり、へのポインターuv_fs_tではありません)。

これは、それopen_reqが関数(または関数へのポインター)であることを示しています。さらに役立つように、この関数の宣言とopen_req、関数自体の名前ではなく関数へのポインターである場合に変数を初期化する方法を使用して、元の質問を編集してください。

編集:

質問をもう一度確認した後、open_reqほとんどの場合、元のエラーは発生していません。コードを元の状態に戻す必要があります。

一方、on_open問題を引き起こす可能性が非常に高いです。この関数をプロトタイプで宣言します

void on_open(uv_fs_t);

しかし、定義の最初の行は

void on_open(uv_fs_t *req)

*関数定義の最初の行からを削除して、何が起こるかを確認します。

于 2013-03-25T20:47:46.250 に答える