Question

Récemment, je concevais une bibliothèque de classes Thread. J'ai créé une classe abstraite Thread comme suit:

class Thread {
public:
    run() { /*start the thread*/ }
    kill() { /*stop the thread*/ }
protected:
    virtual int doOperation(unsigned int, void *) = 0;
};

Les classes de thread réelles hériteraient de cette classe abstraite et implémenteraient la méthode doOperation dans sa propre logique, ce qui est similaire à Modèle de stratégie .

Le problème est que je m'appuie sur une bibliothèque de back-end C qui définit l'exécution du thread dans la fonction suivante:

int startThread(char* name, (int)(*)(unsigned int, void*), int, int, int, void*);

Comme vous pouvez le voir; le second paramètre est un pointeur de fonction sur la boucle du thread (fonction principale), et voici le problème; Étant donné que j'utilise cette fonction C pour démarrer le thread dans la méthode run, je passe l'adresse de reinterpret_cast au second paramètre, ce qui est impossible à cause du manque de correspondance de type.

J'ai essayé d'utiliser <=> pour renvoyer un pointeur, mais ISO-C ++ interdit de renvoyer un pointeur de membre de fonction non initialisé. Je ne sais pas comment surmonter ce conflit. La seule solution, je suppose, consiste à utiliser une méthode statique. Cependant, mon schéma de conception explose!

Était-ce utile?

La solution

Tout d’abord, veillez à lire le lien fourni par Michael Burr, car il contient de bonnes informations. Ensuite, voici le pseudo-code ish C ++ pour cela:

int wrapperDoOperation(int v, void *ctx)
{
    Thread *thread = (Thread *)ctx;
    return thread->doOperation(v);
}

class Thread {
public:
    run() {
         startThread("bla", wrapperDoOperation, bla, bla, bla, (void *)this);
    }
    kill() { /*stop the thread*/ }
protected:
    virtual int doOperation(unsigned int) = 0;

friend wrapperDoOperation ......;
};

L’idée est que doOperation, en tant que fonction membre de Thread, n’a pas besoin d’un contexte vide *, vous pouvez simplement conserver ce que vous transmettez comme contexte dans l’objet même. Par conséquent, vous pouvez utiliser le pointeur vide pour passer l'actuel de ce pointeur à la fonction doOperation. Notez que les détails void * ne sont pas visibles par les utilisateurs de votre classe, ce qui est agréable.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top