Designmuster für ausnahmesichere Trampoline

Diese Frage folgt ausHie. Die vorherige Frage war jedoch so falsch formuliert (fälschlicherweise), dass vorgeschlagen wurde, dass ich sie erneut von Grund auf stelle.

Ich habe eine Tabelle mit C-Funktionszeigern.

Einiger C-Code (nennen wir ihn lib-X) hat einen grundlegenden Baustein (nennen wir ihn ein X-Objekt). Jedes X-Objekt kann Funktionen für diese Tabelle aufrufen.

Diese Tabellenfunktionen haben im Allgemeinen unterschiedliche Signaturen (siehe typedefsHie), obwohl es möglich ist, dass mehrere Funktionen dieselbe Signatur verwenden. Die Tabelle enthält ungefähr 100 dieser Funktionen.

n C ++ habe ich für jedes X-Objekt eine zugehörige Final: Base-Klass

Und ich möchte diese Aufrufe an die entsprechende C ++ Final-Instanz des X-Objekts weiterleiten, aber ich möchte dies in try / catch einschließen, da der C ++ - Konsument möglicherweise ein fehlerhaftes Final bereitstellt.

So habe ich eine C ++ - Basisklasse, die eine virtuelle Funktion für jeden Eintrag in der Tabelle hat.

Ich habe dann eine C ++ Final-Klasse (möglicherweise viele; Final1 Final2 Final3 usw.), die von der Basisklasse abgeleitet ist.

So jetzt muss ich nur noch einen Handler schreiben, der

Ruft den ersten 'self'-Parameter ab (der immer ein Zeiger auf das X-Objekt ist, das die Funktion aufgerufen hat)

Ruft die zugeordnete C ++ - Basisklasseninstanz ab.

In einem try catch-Block wird die entsprechende virtuelle Funktion aufgerufen, wobei alle verbleibenden Parameter durch @ weitergeleitet werde

... was die Außerkraftsetzung in Final tatsächlich auslöst.

Es ist ein bisschen so, als würde man versuchen, die Handlung für Inception zu verstehen. lib-X ist in der Tat die Python-Laufzeit, obwohl ich versuche, die Dinge allgemein zu halten.

Das Ding ist, dass es Dutzende dieser Funktionen gibt, und dies führt zu etwas sehr chaotischem und nicht zu wartendem C ++ - Code - wenn ich für jede manuell eine Trampolinfunktion schreiben muss, sieht das so aus:

extern "C" PyObject *call_handler( PyObject *self, PyObject *args, PyObject *kw )
{
    try
    {
        PythonExtensionBase *p = getPythonExtensionBase( self );
        if( kw != NULL )
            return new_reference_to( p->call( Object(args), :Object(kw) ) );
        else
            return new_reference_to( p->call( Object(args), Object() ) );
    }
    catch( Py::Exception & )
    {
        return NULL; // indicate error
    }
}

(QuelleHie)

Ich versuche, ein kompaktes Design zu entwickeln, das dieses ausnahmesichere Trampolin ermöglicht.

Mein aktueller Fortschritt ist [ENTFERNT, siehe Antwort unten]

Antworten auf die Frage(4)

Ihre Antwort auf die Frage