Ich möchte in C ++ geschriebenen Code zu einer Bibliothek machen, die in Python aufgerufen werden kann. Es gab jedoch eine große Mauer namens Cython.
Dies ist Bridge von C ++ zu Python "Cython" -Kurs: So übergeben Sie ein C ++ - Klassenobjekt an ein Klassenobjekt auf der Python-Seite. Teil 2 ist eine Fortsetzung.
Wie immer werde ich den Code auf github here veröffentlichen. !!
Angenommen, Sie definieren eine Enum-Klasse auf der C ++ - Seite und haben sie als Eigenschaft der Klasse. Wenn Sie diese Eigenschaft zu diesem Zeitpunkt mit Getter usw. erhalten, ist der Rückgabewert natürlich die Enum-Klasse. Bei der Konvertierung in Cython handelt es sich bei diesem Rückgabewert um eine Klasse, die auf der Python-Seite nicht definiert ist. Daher muss sie nach der Definition in Cython analysiert und zurückgegeben werden.
Lassen Sie uns zunächst einen kurzen Blick darauf werfen, wie Enum in C ++ und Python geschrieben wird.
enum class Color{
RED = 0,
GREEN = 1,
BLUE = 2
};
class Color(Enum):
RED = 0
GREEN = 1
BLUE = 2
Fügen Sie die Eigenschaft (Gruppe) der Enum-Klasse zu TestClass1.h und TestClass1.cpp hinzu, die bisher geschrieben wurden. Entsprechend haben wir auch Getter und Setter für die Gruppeneigenschaft hinzugefügt.
cpp_library/TestClass1.h
enum class EnumForTestClass1{
ZERO = 0,
ONE = 1
};
class TestClass1{
private:
TestClass2 property_test_class2;
EnumForTestClass1 group;
public:
//~ Abkürzung
void set_group(EnumForTestClass1 group);
EnumForTestClass1 get_group();
cpp_library/TestClass1.cpp
EnumForTestClass1 TestClass1::get_group(){
return this->group;
}
void TestClass1::set_group(EnumForTestClass1 group){
this->group = group;
}
Dieser Getter und Setter werden in Cython konvertiert, dh die Enum-Klasse auf der C ++ - Seite und die Enum-Klasse auf der Python-Seite sind verbunden.
Wie gewöhnlich
cytyon/test_class1.C bis pxd++Definieren Sie die Neben-Enum-Klasse. Die Definitionsmethode ist gemäß der folgenden Datei unterteilt.
Fügen Sie danach die Definitionen des erstellten Getters und Setters hinzu.
#### **`cython/test_class1.pxd`**
```pxd
cdef extern from "../cpp_library/TestClass1.h":
cdef cppclass EnumForTestClass1:
EnumForTestClass1()
cdef extern from "../cpp_library/TestClass1.h" namespace "my_library":
cdef EnumForTestClass1 ZERO
cdef EnumForTestClass1 ONE
cdef extern from "../cpp_library/TestClass1.h" namespace "my_library":
cdef cppclass TestClass1:
#~ Abkürzung
void set_group(EnumForTestClass1 group)
EnumForTestClass1 get_group();
Fügen Sie die gleiche Beschreibung auch zu `` `cython / my_library.pxd``` hinzu.
cython/my_library.pxd
cdef extern from "../cpp_library/TestClass1.h" namespace "my_library":
cdef cppclass EnumForTestClass1:
EnumForTestClass1()
cdef extern from "../cpp_library/TestClass1.h" namespace "my_library":
cdef EnumForTestClass1 ZERO
cdef EnumForTestClass1 ONE
cdef extern from "../cpp_library/TestClass1.h" namespace "my_library":
cdef cppclass TestClass1:
#~ Abkürzung
void set_group(EnumForTestClass1 group)
EnumForTestClass1 get_group();
Sobald dies erledigt ist, besteht der nächste Schritt darin, den Inhalt von Getter und Setter in `` `cython / tests_class1.pyx``` zu schreiben. Wenn Sie den Code zuerst schreiben, sieht er folgendermaßen aus:
cython/tests_class1.pyx
cpdef enum Py_EnumForTestClass1:
Py_ZERO = 0
Py_ONE = 1
cdef class TestClass1Cython:
cdef TestClass1* ptr
def set_group(self, Py_EnumForTestClass1 group):
return self.ptr.set_group(<EnumForTestClass1> group)
def get_group(self):
cdef:
EnumForTestClass1* cpp_enum_for_test_class1 = new EnumForTestClass1()
cpp_enum_for_test_class1[0] = <EnumForTestClass1>self.ptr.get_group()
if(<int>cpp_enum_for_test_class1[0] == <int>Py_EnumForTestClass1.Py_ZERO):
return Py_EnumForTestClass1.Py_ZERO
elif(<int>cpp_enum_for_test_class1[0] == <int>Py_EnumForTestClass1.Py_ONE):
return Py_EnumForTestClass1.Py_ONE
Definieren Sie zunächst die Enum-Klasse, die von Python aus aufgerufen werden kann, mit `` `cpdef enum Py_EnumForTestClass1```.
Als nächstes wird in Bezug auf den Setter `Py_EnumForTestClass1``` von der Python-Seite empfangen und an die C ++ - Seitenfunktion übergeben, indem es mit`
Auch wenn es in Bezug auf Getter etwas redundant ist, wird das, was als Enum-Objekt auf der C ++ - Seite in `<EnumForTestClass1> self.ptr.get_group ()`
übergeben wurde, mit `Py_EnumForTestClass1
auf der Python-Seite gleich ist, und das
`` Py_EnumForTestClass1```-Objekt wird entsprechend zurückgegeben.
Mit dem oben Gesagten ist es möglich, die Enum-Klasse auf der Python-Seite mit der Enum-Klasse auf der C ++ - Seite und die Enum-Klasse auf der C ++ - Seite mit der Enum-Klasse auf der Python-Seite zu analysieren.
Endlich wie immer
python setup.py install
Lassen Sie uns kompilieren und testen mit.
#### **`test.py`**
```py
import my_library as myl
if __name__ == "__main__":
cl1 = myl.test()
test1 = myl.Py_EnumForTestClass1.Py_ZERO
cl1.set_group(test1)
test2 = cl1.get_group()
print(test2)
als Ergebnis,
(myenv) root@e96f489c2395:/from_local/cython_practice# python test.py
0
Es wurde bestätigt, dass die Enum-Klasse festgelegt werden und zur C ++ - Eigenschaft gelangen konnte.
Dieses Mal erklärte ich, dass beim Konvertieren einer in C ++ geschriebenen Bibliothek nach Cython, damit sie von Python aus verwendet werden kann, die in C ++ deklarierte Enum-Klasse an die Enum-Klasse auf der Python-Seite übergeben wird.
Inzwischen sollten Sie in der Lage sein, die meisten benutzerdefinierten Objekte auf der C ++ - Seite an die Python-Seite zu übergeben.
Das nächste Mal möchte ich darüber schreiben, wie Cython mit Funktionsüberladungen umgeht, die häufig auf der C ++ - Seite geschrieben werden.
Diesmal.
Ende.
Recommended Posts