2016-02-20 1 views
1

J'utilise une bibliothèque fournie par mon professeur pour une affectation de classe, donc je ne peux pas révéler trop de mon code. Voici une partie de l'API:Comment affecter une fonction à un pointeur de fonction qui prend un argument de type void *?

typedef void (*thread_startfunc_t) (void*); 
int thread_libinit(thread_startfunc_t func, void *arg); 
int thread_create(thread_startfunc_t func, void *arg); 

thread_libinit initializes the thread library. A user program should call 
thread_libinit exactly once (before calling any other thread functions). 
thread_libinit creates and runs the first thread. This first thread is 
initialized to call the function pointed to by func with the single 
argument arg. Note that a successful call to thread_libinit will not 
return to the calling function. Instead, control transfers to func, and 
the function that calls thread_libinit will never execute again. 

thread_create is used to create a new thread. When the newly created 
thread starts, it will call the function pointed to by func and pass it the 
single argument arg. 

Pour tester, j'ai écrit le code suivant:

void pHello(int i) 
{ 
    cout << "Hello from thread " << i << endl; 
} 

... [In Main] ... 

typedef void (*thread_startfunc_t) (void* i); 
thread_startfunc_t pSalute = & pHello; //Does not compile 

thread_libinit(pSalute,1); 

Je reçois l'erreur:

In function `int main(int, char**)`: 
error: invalid conversion from `void (*) (int)' to `thread_startfunc_t{aka void(*) (void*)}' [-fpermissive] 

Je pensais une variable de pointeur de vide peut pointer vers une variable. Alors pourquoi ne peut-il pointer vers l'int de la fonction pHello? Comment affecter une fonction au pointeur de fonction?

Répondre

2

Un pointeur de fonction avec une signature spécifique (donnée comme type de retour plus types de variables) ne peut pointer que vers des fonctions ayant la même signature.

Dans votre cas, où il semble que vous ne pouvez pas changer le type de pointeur de fonction, vous pouvez modifier votre fonction pHello selon

void pHello(void* i) 
{ 
    std::cout << "Hello from thread " << *static_cast<int*>(i) << std::endl; 
} 

typedef void (*thread_startfunc_t) (void*); 

int main() 
{ 
    thread_startfunc_t f = pHello; 

    //or point to a non-capturing lambda: 
    thread_startfunc_t f2 = [](void *) { std::cout<<"hi"<<std::endl; }; 
} 

Ce n'est cependant pas vraiment agréable code C++.

1

I thought a void pointer variable can point to any variable. So why can't it point to the int of the function pHello?

Parce que l'instruction n'est pas correcte. En C++, vous devez utiliser des conversions pour cela. C'est l'une des grandes différences entre C++ et C. Voir aussi Difference between void pointers in C and C++

Vous pouvez tester ceci. Compilez votre code en tant que C, supprimez les fonctionnalités C++ comme <iostream>, et cela devrait fonctionner comme prévu.

How do I assign a function to the function pointer?

Modifier la signature de pHello à:

void pHello(void*) 

A l'intérieur de la fonction, vous devez utiliser moulages pour obtenir la valeur du pointée.

De même, lorsque vous appelez thread_libinit, le deuxième argument doit être l'adresse d'un objet int qui demeure jusqu'à la fin de la fonction.


Bien sûr, rien de tout cela n'est très agréable ou moderne C++. API de votre professeur devrait plutôt faire usage de std::function.

+0

Bien que vous avez ajouté le (presque sûr) devinez pourquoi cette erreur se produit, +1. – davidhigh