C ++ - Wrapper für Funktionsaufrufer mit verschiedenen Pakettyp

Ich habe viele Vorlagen mit variabler Pack-Erweiterung studiert, kann aber immer noch nicht alle Artikel zusammenstellen, die ich hier gefunden habe, um mein Ziel zu erreichen. Bitte entschuldigen Sie, dass ich wahrscheinlich überflüssig bin. Ich bin an einige APIs gebunden und an einige Funktionssignaturen gebunden, wie hier:

static bool WrapperFunction(JSContext *cx, unsigned argc, JS::Value *vp)

Ich versuche, Objekte und Funktionen, die unter SpiderMonkey in Javascript verwendet werden sollen, zu verpacken. Um eine C-API zu integrieren, müssen Wrapper für Objektdaten und Wrapper-Methoden für ein Objekt implementiert werden.

Meine Lösung hat mich zu der folgenden Logik des Wrappers geführt, um Methoden mit mehreren Argumenten aufrufen zu können, aber ich weiß nicht, wie ich das erreichen soll:

    template<typename jsType, typename jsReturnType, typename MethodType, MethodType Method, typename... jsParamType>
static bool VAMethodRet(JSContext *cx, unsigned argc, JS::Value *vp)
{
    JS::CallArgs args = CallArgsFromVp(argc, vp);

    jsReturnType::PrivateType result = jsReturnType::PrivateTypeDefaultValue();

Hier fangen meine Ausgaben an.

Erster Schritt Erweitern Sie ... jsParamType ..., und rufen Sie für jeden jsParamType eine Methode auf, um eine Objektinstanz für die Wrapper-Klasse zu erstellen, die mit dem entsprechenden Argument aus Argumenten übereinstimmt, um den Aufruf der C-API-Funktion vorzubereiten.

Mit anderen Worten, jsParamType gibt den Typ an, den es umschließt, damit es das C-Typ-Objekt für jeden Parameter extrahieren kann, der an die C-API-Funktion übergeben werden soll.

Der erste jsParamType entspricht den args [0], der zweite jsParamType den args1 etc., bis zum letzten jsParamType, der dem args [argc] entspricht.

Es ist möglich, weniger Elemente in args als sizeof ... jsParamType abzurufen. In diesem Fall sollte das Basis-C-Objekt mit einem Standardwert initialisiert werden.

Die Metainformationen von Parametern oder Objektwrappern werden bereits mit statischen Methoden erzielt (z. B. jsParamType :: jsType :: PrivateTypeDefaultValue ()).

Eventuell sollte das erweiterte Paket ein Array oder ein Vektor heterogener Objekte sein.

Die Matching-Funktion sollte basierend auf jsParamType als Vorlage dienen, aber auch den Index des erweiterten Variadic Packs und der lokalen Variablen args abrufen, um das richtige Objekt zum Parsen zu erhalten - hier ist meine erste Ausgabe:

Wie wird der Index an die Methode übergeben?

Ich habe versucht, mich von hier zu inspirieren, aber ich kann es nicht zum Laufen bringen:Aufrufen einer Funktion für jedes Argument einer variablen Vorlage und eines Arrays

Zweiter Schrit. Danach plane ich eine ähnliche Technik wie hier:Argumentindex beim Entpacken der Argumentliste mit variablen Vorlagen erhalten, um die C-API-Funktion mit den richtigen Argumenten aufzurufen - ist das möglich?

Dritter Schrit. Basierend auf einer statischen Funktion von jsParamType namens IsOut () werden die out-Werte den Inhalt der lokalen Variablen args aktualisieren. Dies sollte jedoch erneut mit einer neuen Erweiterung erfolgen, ähnlich wie im ersten Schritt, um einige zurückzusetzen Werte unter Verwendung der in jsParamType-Elementen vorhandenen Typinformationen.

Das letzte, was zu tun wäre, wäre den Rückgabewert zu setzen, was trivial ist.

Legend: jsType ist ein Typ der Struktur, die den Zeiger auf die C-API-Funktionen enthält, da diese vom Anbieter der C-API gruppiert werden. jsReturnType ist der Rückgabetyp. (nur als Referenz hier ...)Method ist eine aufzurufende C-API-Methode mit dem MethodType Art

Bitte hilf mir, solchen Code zu schreiben, da ich ihn nicht zum Laufen bringen kann. Ich bitte nicht, für mich zu denken und meine privaten Programmierer zu sein. Ich habe gerade keine Erfahrung mit diesem Teil des Präprozessors, ich sehe viele Beispiele, viele Wurffehler, oder ich kann sie nicht erweitern, um die obige Funktion zu erreichen. Vielen Dank

EDIT 1

Danke für die Antwort, AndyG. Hier ist der mehr oder weniger Pseudocode:

    // *jsType* is a type of the struct containing the pointer to the C API functions, as these are grouped by the C API's provider.
    // *jsReturnType* is the return type. (just for reference here...)
    // *Method* is a C API method to be called, having the *MethodType* type.
    // The non-template part of the function signature is needed untouched by SpiderMonkey

    template<typename jsType, typename jsReturnType, typename MethodType, MethodType Method, typename... jsParamType>
static bool VAMethodRet(JSContext *cx, unsigned argc, JS::Value *vp)
{
    // get the collection of passed arguments (SpiderMonkey stuff), in args, each element accessible by index
    // argc is the number of parameters passed from javascript
    WrappersCollection args = GetCallArgsFromVp(argc, vp);

    jsReturnType::PrivateType result = jsReturnType::PrivateTypeDefaultValue(); // creates an instance of a return value wrapper to receive the return value later

    // 1. Match wrappers in the WrappersCollection against their types in order to get their C type values
    CDataCollection cdata = array or vector of heterogeneous objects (int, char*, structs etc.);
    for each (jsParamType in the variadic pack ...)
    {
         cdata[jsParamTypeIndex] = Match<jsParamType, jsParamTypeIndex>(args);
    }
    // the above should be done by expanding the pack somehow
    // with emphasis on checking if argc[jsParamTypeIndex] was passed actually, because it's possible to have jsParamTypeIndex > argc
    // I don't know how to do it otherwise, by matching some param types variadic pack against a variadic pack of data arguments with different number of elements

    // 2. Transform the cdata collection into a variadic parameters pack in order to pass them to the C function.
    // The amount of args is specified by the function
    result = CFunction(cdata...);

    // 3. Update returned data in *out* params in the collection of wrapper objects received in the first place
    // index of the param in pack is necessary again
    // due to the different number of elements in the param types variadic pack versus the variadic pack of data arguments
    for each (jsParamType in the variadic pack ...)
    {
         if (jsParamType::IsOUT())
         {
              cdata[jsParamTypeIndex] = MatchBack<jsParamType, jsParamTypeIndex>(args);
         }
    }

    // the rest of things to do
    MatchReturnValue(result);

    return true; // SpiderMonkey needs to know the success of the operation
}

Ist das verständlicher genug?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage