变量声明,使用libuv

时间:2013-03-25 20:24:48

标签: c libuv

我正在尝试学习如何使用libuv。我在Mac OS X上并下载并安装了库。我可以编译并运行小型测试程序,只启动一个回调循环,然后退出,因为没有观察者,另一个创建一个空闲的观察者,并在时间用完时退出。

我一直在尝试浏览文件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)

我已将示例代码缩减到仍会出错的min。

#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 *)'”。我得到相同的错误,而声明是在主要内部或不是。如果我将声明更改为指针声明

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代码,看看我是否可以解决它但是代码很大,我使用的是“这里的libuv简介”:http://nikhilm.github.com/uvbook/这就是示例代码来自。

我可以使用其他任何示例代码源来尝试找出这个库吗?在我的宣言中有什么明显的我做错了吗?我不知道在哪里寻找澄清或如何使用libuv的例子。

修改更新 在libuv代码中,在uv.h文件中。我找到了

typedef struct uv_fs_s uv_fs_t;

我在代码中一直在寻找的东西之一是实际定义了这个结构。我使用google搜索了typedef并了解了一下如何使用typedef来创建名称,以便每次要声明struct的实例时都不必键入struct。虽然有些人似乎认为这是一种可怕的做法,但其他人认为它很棒。我删除了部分内容以获取最小样本作为另一个类型为us_fs_t的声明,名为close_req。我直接从那个复制了我的声明格式。

我会看到我能找到关于函数指针的内容,我只是模糊地熟悉它们,它至少让我开始寻找它。

我找到了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;
}

1 个答案:

答案 0 :(得分: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)

请注意,第二个参数的类型为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);

第二个参数(&open_req)获取open_req的地址并创建所需的指针。这个应该正常工作。但是,从您的原始错误消息,我认为您没有发布所有相关代码。让我们看看这个错误消息:

  

从'void(*)(uv_fs_t)'无效转换为'void(*)(uv_fs_t *)'

这表明编译器需要一个指向函数的指针,该函数返回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)

从函数定义的第一行中删除*,看看会发生什么。