从"void*"到"void(*)(void*)"的转换无效

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

本文关键字:quot void 无效 转换      更新时间:2023-10-16

所以我目前正在使用,或者至少正在尝试编写一个使用这个C pthread线程池库的程序。

值得注意的是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);

我确信我只是错误地调用了函数,但不知道如何正确地调用它。那么我该如何修复呢?

编辑/更新:

我更改了功能以执行以下操作:

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

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

void (*function_p)(void*)

意味着您的函数必须具有返回类型void,并将单个void指针作为参数。你的职能并非如此。

thpool_add_work需要一个指向返回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);

如果你真的需要这个返回值,你需要更进一步,传递一个指向某个结构的指针:

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之类的东西可能会更好。