2

重複の可能性:
void ポインター: C と C++ の違い

こんにちは、次の機能があります。

void task2(int a)
{
    printf("  Task 2 running..\n");
    sleep(2);
    printf("  Task 2 exiting..\n");
}

thpool_add_work(threadpool, (void*)task2, (void*)a);

int thpool_add_work(thpool_t* tp_p, void *(*function_p)(void*), void* arg_p)
{
    // some code here
}

上記のコードは C ではうまく機能しますが、C++ ではコンパイルできません。次のエラーが表示されます。

error: invalid conversion from ‘void*’ to ‘void* (*)(void*)’
error:   initializing argument 2 of ‘int thpool_add_work(thpool_t*, void* (*)(void*), void*)’

このエラーの理由がわかりません。ファイル拡張子を CPP に変更してコンパイルすると、このエラーが発生する理由はわかりますか?

4

2 に答える 2

2

引数task2の型と一致するように署名を変更する必要があります。thpool_add_work

void* task2(void* a)

スレッドを作成する呼び出しは次のようになります

thpool_add_work(threadpool, task2, &a);

だとしaますint

の引数を使用する必要がある場合はtask2、次のようにすることができます。

int ia = *(int*)a;

OPコメントに答えるために更新

thpool_add_workvoid*理由により、引数を持つ関数が必要です。このように、タイプセーフでない方法ではありますが、任意の種類のパラメーターをスレッド関数に渡すことができます。

に変換したパラメータのアドレスをvoid*の第 3 引数として渡しますthpool_add_workvoidその後、ポインターを期待されるパラメーターの型へのポインターにキャストし、逆参照してパラメーターの値を取得します。上記の例を挙げましたがint a、フロートがどのように見えるか:

void* test3(void* a)
{
float fa = *(float*)a;
.....
return NULL;
}
于 2012-10-04T06:53:47.580 に答える
0

これを試して

thpool_add_work(threadpool, (void* (*)(void*))task2, (void*)a);

C は任意の型に自動的に変換void*しますが、C++ は変換しません。

typedef を使用してコードを改善できます

typedef void* (*worker_func_t)(void*);

thpool_add_work(threadpool, (worker_func_t)task2, (void*)a);

int thpool_add_work(thpool_t* tp_p, worker_func_t function_p, void* arg_p)
{
    // some code here
}
于 2012-10-04T06:49:32.417 に答える