Kesalahan typecast C++ [duplikat]

Kemungkinan Duplikat:
void pointer: perbedaan antara C dan C++

Hai, saya memiliki fungsi berikut:

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
}

Kode di atas berfungsi baik dengan C, tetapi tidak dapat dikompilasi di C++. Saya mendapatkan kesalahan berikut:

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

Saya tidak dapat mengetahui alasan kesalahan ini. Adakah yang tahu mengapa kesalahan ini muncul ketika saya mengubah ekstensi file menjadi CPP dan mengkompilasi?


person webgenius    schedule 04.10.2012    source sumber
comment
Anda perlu memposting lebih banyak kode – seperti deklarasi fungsi dan objek.   -  person Konrad Rudolph    schedule 04.10.2012
comment
Bukankah ini karena void* secara implisit dapat dikonversi di C, tetapi tidak di C++?   -  person verdesmarald    schedule 04.10.2012
comment
Di C++, tidak sah mengonversi penunjuk data (yaitu void*) menjadi penunjuk fungsi (yaitu void* (*)(void*)). Namun banyak kompiler yang membiarkan Anda lolos begitu saja. Saya akan menghapus atau menyesuaikan pemeran task2 yang Anda buat saat menelepon thread_add_work. Saya juga akan menghapus (void*) pemeran a yang sepertinya tidak ada gunanya. Terlalu banyak cast selalu merupakan pertanda buruk, itu hanya menyembunyikan kesalahan   -  person john    schedule 04.10.2012
comment
apa itu tugas2? apakah itu sebuah fungsi?   -  person weima    schedule 04.10.2012
comment
Baru saja memperbarui konten tugas2 di pertanyaan   -  person webgenius    schedule 04.10.2012


Jawaban (2)


Anda harus mengubah tanda tangan task2 agar sesuai dengan jenis argumen thpool_add_work:

void* task2(void* a)

Panggilan yang menciptakan thread akan menjadi

thpool_add_work(threadpool, task2, &a);

dengan asumsi bahwa a adalah int.

Jika Anda perlu menggunakan argumen task2, Anda dapat melakukan hal berikut:

int ia = *(int*)a;

Pembaruan untuk menjawab komentar OP

thpool_add_work mengharapkan fungsi dengan argumen void* karena suatu alasan. Sedemikian rupa, Anda dapat meneruskan segala jenis parameter ke dalam fungsi thread, meskipun dengan cara yang tidak aman.

Anda meneruskan alamat parameter yang dikonversi ke void* sebagai argumen ke-3 dari thpool_add_work. Setelah itu, Anda melemparkan pointer ke void kembali ke pointer ke tipe parameter yang Anda harapkan dan melakukan dereferensi untuk mendapatkan nilai parameter. Saya berikan contoh untuk int a di atas, sekarang bagaimana tampilannya untuk float:

void* test3(void* a)
{
float fa = *(float*)a;
.....
return NULL;
}
person Andrey    schedule 04.10.2012
comment
task2 perlu mengubahnya menjadi int, dan task3 perlu mengubah void* menjadi float. Saya tidak yakin bagaimana mengubah parameter menjadi void* a akan membantu. Bisakah Anda menjelaskannya lebih lanjut? - person webgenius; 04.10.2012
comment
@webgenius: Jawabannya diperbarui - person Andrey; 04.10.2012

Coba ini

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

C mengonversi void* ke tipe apa pun secara otomatis, C++ tidak.

Anda dapat meningkatkan kode dengan 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
}
person john    schedule 04.10.2012