从“void *”到“void (*)(void*)”的无效转换

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

所以我目前正在使用,或者至少试图编写一个利用 this C pthread threadpool library.

的程序

值得注意的是 thpool.h 中的以下函数:

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

我尝试添加作品的代码如下:

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

这给了我以下错误:

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

我确定我只是调用了函数错误之类的,但不知道如何正确地调用它。那我该如何解决呢?

Edit/Update:

我更改了函数以执行以下操作:

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

这很好用。现在的问题是我如何传递一个字符串数组以便我可以将数据作为参数访问?

void (*function_p)(void*)

表示您的函数必须具有 return 类型 void 并采用单个 void 指针作为参数。你的函数不是这种情况。

thpool_add_work 需要一个指向函数的指针 returns void 并采用单个 void* 参数。你的 testpool 不是这样的功能。指向 testpool 的指针的类型为

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

这与预期有很大不同

void (*)(void*)

如果你想在那个库中使用那个函数,你需要稍微改变它:

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

请注意,我更改了参数类型,向 string* 添加了强制转换,并删除了 return 语句。现在你可以这样调用 thpool_add_work

thpool_add_work(thpool, testpool, input);

如果你真的需要那个 return 值,你需要更进一步并传递一个指向某个结构的指针:

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

使用此版本,您的呼叫站点将如下所示:

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;

最后要注意的是,在异步调用完成之前保持参数对象处于活动状态可能是一个挑战。像我在这里所做的那样将它们声明为自动变量意味着您必须等待异步调用完成才能退出声明它们的范围,并且您不能真正使用 std::unique_ptrstd::shared_ptr 与 C 库。由于您正在编写 C++,因此您最好使用 std::async 之类的东西。