Variable declarations, using libuv

2019-02-24 12:34发布

问题:

I am trying to learn how to use libuv. I am on a mac OS X and have the library downloaded and installed. I can compile and run small test programs one only starts a callback loop and then exits since there are no watchers, the other creates an idle watcher and exits when the time runs out.

I have been trying to go through the samples for the file io and have been running into problems. The function prototype for the function to obtain a file descriptor is:

 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)

I have cut the sample code down to the min that will still have the error.

#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);
}

My declaration of open_req is exactly like the declaration of close_req which appears in the complete code sample and doesn't produce and error. I added the declaration for open_req because the compiler was giving me a "‘open_req’ was not declared in this scope" error. When I added the declaration it changed the error to "invalid conversion from ‘void (*)(uv_fs_t)’ to ‘void (*)(uv_fs_t*)’". I get the same error rather the declaration is inside main or not. If I change the declaration to a pointer declaration

uv_fs_t* open_req; 

then I get the error:

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*))

I am trying to go through the actual libuv code to see if I can figure it out but the code is huge, I am using the "An Introduction to libuv" found here: http://nikhilm.github.com/uvbook/ and that is where the sample code came from.

Is there any other source of sample code that I can use to try and figure out this library? Is there anything obvious that I am doing wrong in my declaration? I am not sure where to look for clarification or examples on how to use libuv.

Edit update In the libuv code, in the uv.h file. I find

typedef struct uv_fs_s uv_fs_t;

one of the things I have been looking for in the code is where this struct is actually defined. I have searched using google for typedef and learned a bit about how typedef is used to make the name so that you don't have to type struct every time that you want to declare an instance of the struct. Though some people seem to think it is a terrible practice and others think it is great. Part of what I removed to get a minimum sample as another declaration of a type us_fs_t called close_req. I copied the format for my declaration directly from that one.

I will see what I can find about pointers to functions, I am only vaguely familiar with them and it at least gives me somewhere to start looking.

I have found the function definition for 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:

You state that the prototype for the function uv_fs_open is

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

Note that the type of the second argument is uv_fs_t*. So when you declare open-rec as

uv_fs_t open_req;

And then call uv_fs_open() with

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

the second argument (&open_req) takes the address of open_req and creates the required pointer. This should work just fine. However, from your original error message, I think you did not post all of the relevant code. Let's look at this error message:

invalid conversion from ‘void (*)(uv_fs_t)’ to ‘void (*)(uv_fs_t*)’

This states that the compiler expects a pointer to a function which returns void and takes a single parameter which is a pointer to a uv_fs_t. On the other hand, you are providing a pointer to a function which returns void and takes a single parameter of type uv_fs_t (i.e. not a pointer to uv_fs_t).

This suggests that open_req is a function (or a pointer to a function). In order to help you further, please edit your original question with the declaration of this function as well as how you initialize the open_req variable if it is a pointer to a function rather than the name of the function itself.

Edit:

After a second look at your question, open_req most likely doesn't cause the original error. You should change your code back to the way it was originally.

On the other hand, on_open very likely causes the problem. You declare this function with the prototype

void on_open(uv_fs_t);

but the first line of the definition is

void on_open(uv_fs_t *req)

Remove the * from the first line of the function definition and see what happens.



标签: c libuv