首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从“void*”到“void(*)(void*)”的无效转换

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

Stack Overflow用户
提问于 2017-02-11 19:05:59
回答 2查看 3.3K关注 0票数 0

因此,我目前正在使用,或者至少试图编写一个利用这个C线程线程池库。的程序

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

代码语言:javascript
复制
int thpool_add_work(threadpool, void (*function_p)(void*), void* arg_p);

我试图添加的代码如下所示:

代码语言:javascript
复制
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:在函数‘int(int,char**)’中: main.cpp:167:55: main.cpp:167:55:从‘void*’到‘void(*)(void*)’-fpermissive thpool_add_work(thpool,(void*)testpool,(void*)输入)的无效转换;^在main.cpp:29:0: thpool.h:67:5中包含的文件中:注意:初始化‘int thpool_add_work(线程池,void (*)( void* ),void *)’int thpool_add_work(线程池,void (*function_p)(void*),void*arg_p)的参数2;

我确信我只是简单地把函数调用错了什么的,但不知道如何正确地完成它。那我该怎么解决呢?

编辑/更新:

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

代码语言:javascript
复制
void testpool(void*){
    // Pass three strings to it. Which we will end up displaying.
    cout << "Hellooooo." << endl;
}

这个很好用。现在的问题是如何传递这个字符串数组,这样我就可以以参数的形式访问数据了?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-02-11 19:50:46

thpool_add_work需要一个指向返回void并接受单个void*参数的函数的指针。您的testpool不是这样的函数。指向testpool的指针具有以下类型

代码语言:javascript
复制
int (*)(string (&)[3])

这与预期的有很大的不同

代码语言:javascript
复制
void (*)(void*)

如果您想在该库中使用该函数,则需要稍微修改它:

代码语言:javascript
复制
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

代码语言:javascript
复制
thpool_add_work(thpool, testpool, input);

如果确实需要返回值,则需要进一步传递指向某个结构的指针:

代码语言:javascript
复制
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;
}

有了这个版本,您的呼叫站点将如下所示:

代码语言:javascript
复制
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;

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

票数 1
EN

Stack Overflow用户

发布于 2017-02-11 19:09:00

代码语言:javascript
复制
void (*function_p)(void*)

意味着您的函数必须具有返回类型void,并接受单个void指针作为参数。对于您的功能来说,情况并非如此。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42180039

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档