Wir haben eine Reihe von C++ - Klassen, die wir Python mit Swig aussetzen. Wir fügen den Methoden oft neue Argumente hinzu. Auf der anderen Seite haben wir eine Reihe von Python-Skripten, die wir so einfach wie möglich verwalten möchten. Wenn wir also die Menge der Argumente einer exponierten Methode in C++ ändern, wollen wir nicht alle unsere Python-Skripte ändern müssen, die diese Methode verwenden. Zu diesem Zweck haben wir für jede unserer C++ - Klassen eine sekundäre Schnittstellenklasse (auch C++ - Klasse) erstellt, die einen Zeiger auf eine Instanz der ursprünglichen Klasse besitzt und eine vereinfachte Schnittstelle zur Verfügung stellt.Swig: Der beste Weg, um eine vereinfachte Schnittstelle zu handhaben
zum Beispiel vorstellen, dass wir eine Klasse A mit einer Methode foo haben:
class A {
public :
void foo (int a, int b, double c, char * d, ....);
};
Und wenn wir zufrieden sind nur die a, b und c Argumente in Python (Standardwert für die andere vorbei).
Wir schaffen eine APY Klasse
class APy {
public :
void foo(int a,int b, double c) {
A->foo(a,b,c,default,default,...);
}
protected :
A * ref;
};
Der Vorteil besteht darin, dass es möglich ist, neue Parameter A :: foo hinzufügen, die Parameter Aufträge ändern, den Namen des Verfahrens und allgemeiner für komplexere Änderungen, kodieren Sie eine Äquivalenz der ursprünglichen Methode ohne Änderung der bestehenden Python-Skripte. Wenn ein Skript ein neues Argument benötigt, ist es außerdem möglich, es über ein Standardargument in APy :: foo hinzuzufügen, ohne dass dies in der ursprünglichen A :: foo-Methode gemacht werden muss.
Der Nachteil ist, dass es delikat ist, mit dem Löschen umzugehen, da es zwei Objekte gibt. Sollten wir A löschen, wenn APy zerstört wird? Es kommt darauf an. Manchmal ist A ein inneres Objekt eines größeren Objekts und sollte nicht zerstört werden. Aber APy sollte immer dann zerstört werden, wenn es vom Python-Skript nicht mehr verwendet wird.
Ich frage mich, ob es möglich wäre, eine einfachere, aber so bequeme Architektur zu entwickeln, indem man direkt die ursprünglichen Klassen und Methoden abbildet, indem man swig bittet, die Argumentliste selbst zuzuordnen und zu vereinfachen.
Ist es möglich, in der .i-Datei Swig zu bitten, die Reihenfolge der Argumente zu ändern, Standardwerte für nicht belichtete Argumente (nicht .h Standardwerte) zu setzen?
Zum Beispiel, wenn ich
void foo(int a, double b, int c);
eine Funktion habe, und ich möchte nur ein und c in umgekehrter Reihenfolge in der Skriptsprache halten und setzen b bis 10,0
Also, wenn ich würde rufen:
foo(3, 5)
es tatsächlich abgebildet werden würde:
foo(5,10.0,3)
Wie auch immer, ich würde gerne von Ihrer Erfahrung hören, was Sie für die beste Art halten, mit solchen Problemen umzugehen.
Ist hier das richtige Werkzeug? Automatisch zeigt Swig jede Änderung an, die Sie vornehmen. Und das versuchen Sie zu verhindern. Für Python-Erweiterungen, die Sie die Python-API von steuern möchten, möchten Sie vielleicht PyCXX betrachten. Sie müssen die Klassen für sich selbst definieren, aber Sie haben die vollständige Kontrolle über die API und können die Abwärtskompatibilität auf Ihre Weise anpassen. –
Wenn die Beziehung zwischen 'A' und' APy' eins zu eins ist. Dh wenn 'APy' exclusive eine eigene Instanz von' A' hat, dann können Sie nach [RAII] (https://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization) 'A' in' APy's' zuweisen und freigeben c'tor' und 'd'tor' jeweils. Für Ihre Anforderung wird "APy" als "Proxy" von "A" fungieren. – sameerkn
Ich kannte PyCXX nicht. Werde einen Blick darauf werfen. Problem ist, dass es nicht mehr möglich wäre, eine Schnittstelle für andere Skriptsprachen zu erzeugen. Das RAII-Design wäre in Ordnung, aber es ist nicht immer möglich. Zum Beispiel. Stellen Sie sich eine Netzwerk- und Knoten-Klasse mit einer Network :: getNode() -Methode vor. Der zurückgegebene Knoten sollte nicht gelöscht werden, da Knoten Teile der Netzwerkobjekte sind (nicht des NodePy-Schnittstellenobjekts). –