从`void *`到`void(*)(void *)`

时间:2017-02-11 19:05:59

标签: c++ pthreads threadpool

所以我目前正在使用,或者至少尝试编写一个使用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);

我确定我只是简单地将函数调用错误或其他东西,但无法弄清楚如何正确地执行它。那么我该如何解决呢?

修改/更新

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

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

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

2 个答案:

答案 0 :(得分:2)

void (*function_p)(void*)

表示您的函数必须具有返回类型void并将单个void指针作为参数。您的功能不是这种情况。

答案 1 :(得分:1)

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_ptr或{{ 1}}带有C库。自从你编写C ++以来,你可能最好使用像std::async这样的东西。