我正在尝试学习如何使用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;
}
答案 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)
从函数定义的第一行中删除*
,看看会发生什么。