简体   繁体   中英

Invalid conversion from `void *` to `void (*)(void*)`

So I'm currently using, or at least trying to write a program that makes use of this C pthread threadpool library.

Of note is the following function in thpool.h :

int thpool_add_work(threadpool, void (*function_p)(void*), void* arg_p);

My code which I'm trying to add a work to is as follows:

int testpool(string (&input)[3]){
    // Pass three strings to it. Which we will end up displaying.
    cout << input[0].c_str() << endl;
    cout << input[1].c_str() << endl;
    cout << input[2].c_str() << endl;
    return 1;
}

string input[3];
input[1] = "Hello";
input[2] = "Test";
input[3] = "Happy.";
thpool_add_work(thpool, (void*)testpool, (void*)input);

This gives me the following error:

 main.cpp: In function 'int main(int, char**)': main.cpp:167:55: error: invalid conversion from 'void*' to 'void (*)(void*)' [-fpermissive] thpool_add_work(thpool, (void*)testpool, (void*)input); ^ In file included from main.cpp:29:0: thpool.h:67:5: note: initializing argument 2 of 'int thpool_add_work(threadpool, void (*)(void*), void*)' int thpool_add_work(threadpool, void (*function_p)(void*), void* arg_p); 

I'm certain that I'm simply calling the function wrong or something, but can't figure out how exactly to do it properly. So how do I fix it?

Edit/Update:

I changed the function to do the following:

void testpool(void*){
    // Pass three strings to it. Which we will end up displaying.
    cout << "Hellooooo." << endl;
}

And this works fine. Now question is how do I pass this an array of strings so I can access the data as arguments?

void (*function_p)(void*)

means that your function MUST have the return type void and takes a single void pointer as argument. This is not the case for your function.

thpool_add_work expects a pointer to a function that returns void and takes a single void* argument. Your testpool is not such a function. A pointer to testpool would have the type

int (*)(string (&)[3])

which is quite a bit different than the expected

void (*)(void*)

If you want to use that function with that library, you will need to change it slightly:

void testpool(void* vinput){
    string* input = static_cast<string*>(vinput);
    // Pass three strings to it. Which we will end up displaying.
    cout << input[0].c_str() << endl;
    cout << input[1].c_str() << endl;
    cout << input[2].c_str() << endl;
}

Note that I've changed the argument type, added a cast to string* , and removed the return statement. Now you can call thpool_add_work like this:

thpool_add_work(thpool, testpool, input);

If you really need that return value, you'll need to go one step further and pass a pointer to some struct:

struct TestpoolArgs
{
    string input[3];
    int ret;
};

void testpool(void* vargs){
    TestpoolArgs* args = static_cast<TestpoolArgs*>(vargs);
    // Pass three strings to it. Which we will end up displaying.
    cout << args->input[0].c_str() << endl;
    cout << args->input[1].c_str() << endl;
    cout << args->input[2].c_str() << endl;
    args->ret = 1;
}

With this version, your call site would look something like this:

TestpoolArgs args;
args.input[0] = "Hello";
args.input[1] = "Test";
args.input[2] = "Happy.";
thpool_add_work(thpool, testpool, &args);
// Wait until testpool runs somehow
int testpool_return_value = args.ret;

One last note is that keeping your argument objects alive until an asynchronous call completes could be a challenge. Declaring them as automatic variables as I've done here means that you have to wait for the asynchronous call to complete before you exit the scope in which they're declared, and you can't really use std::unique_ptr or std::shared_ptr with a C library. You're likely better off using something like std::async since you're writing C++.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM