Frage

Vor kurzem habe ich bereits eine Thread-Klasse Bibliothek entwerfen, ich habe einen Thread abstrakte Klasse wie folgt zusammen:

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

Echt Thread Klassen würden diese abstrakte Klasse erben und doOperation Methode in ihrer eigenen Logik, etwas ähnliches zu implementieren, um Strategie rel="nofollow Muster .

Das Problem ist, dass ich auf einer C-Back-End-Bibliothek verlasse mich die den Faden in der folgenden Funktion definiert ausgeführt wird:

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

Wie Sie sehen können; Der zweite Parameter ist eine Funktion der Schleifenzeiger zum Gewinde (Hauptfunktion), und hier ist das Problem; da ich diese C-Funktion verwenden, um die Gewinde in der run Verfahren zu starten, gebe ich die Adresse doOperation auf den zweiten Parameter, und dies nicht getan werden kann, da der Fehlanpassungstyp.

Ich habe versucht, reinterpret_cast zu verwenden, um einen Zeiger zurück, aber ich ISO-C ++ verbietet einen Zeiger von nicht initialisierten Funktionselement zurück. Ich weiß nicht, wie man diesen Konflikt zu überwinden, eine statische Methode ist die einzige Lösung, die ich denke, aber es bläst meinen Entwurf Muster auf!

War es hilfreich?

Lösung

Als erstes sollten Sie den Link Michael Burr zur Verfügung gestellt lesen, da es gute Informationen enthält. Dann hier ist C ++ ish Pseudo-Code für sie:

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 ......;
};

Die Idee ist, dass doOperation, eine Elementfunktion des Thread ist, braucht keinen void * Kontext, können Sie einfach halten, was Sie als Kontext in dem Objekt selbst passieren würden. Daher können Sie den void-Zeiger verwenden, um den actuall diese Zeiger auf die doOperation passieren. Beachten Sie, dass die void * Details von den Benutzern der Klasse verborgen sind, das ist schön.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top