Ich möchte den in ** c ++ ** geschriebenen Code in eine ** Bibliothek ** verwandeln, die von ** python ** aufgerufen werden kann. Es gab jedoch eine große Mauer namens ** Cython **.
Abhängigkeiten von dunklen Bibliotheken, die eine Umgebung schaffen, die Lust macht, verrückt zu werden. Typkonvertierung, von der ich nicht weiß, was ich tun soll. Dieses Gefühl der Verzweiflung, das mich fragen lässt, ob ich Python, C ++ schreibe oder was ich tue.
Ich habe etwas mehr Zeit, um Cython zu berühren, daher möchte ich es nach und nach zusammenfassen. Ich bin ein Anfänger für Python, C ++ und Cython. Wenn Sie also Fehler haben, lassen Sie es mich bitte wissen.
Dieses Mal werde ich versuchen, ** aus Python als Bibliothek ** sehr einfachen C ++ - Code zu cythonisieren und aufzurufen.
Die minimale ** Ordnerstruktur ** ist wie folgt.
hoge@~/Documents/cython_test> tree .
.
├── cython
│ ├── library_cython.pyx
│ ├── test_library.pxd
│ └── test_library.pyx
├── my_library
│ ├── test.cpp
│ └── test.h
└── setup.py
2 directories, 6 files
setup.py Zuerst musste setup.py die Bibliothek erstellen.
`` `test_library``` ist der Name der Bibliothek, die von Python gelesen werden soll.
Mit anderen Worten, rufen Sie nach dem Erstellen `` `import test_library``` auf.
setup.py
from setuptools import setup, Extension, find_packages
from Cython.Build import cythonize
from Cython.Distutils import build_ext
from distutils import sysconfig
ext_modules = [
Extension(
"test_library", sources=[
"./cython/test_library.pyx",
"./my_library/test.cpp"
],
language="c++"
)
]
setup(
name = "test_library",
cmdclass = {"build_ext": build_ext},
ext_modules= cythonize(ext_modules)
)
In diesem Moment,
Extension(
"test_library", sources=[
"./cython/test_library.pyx",
setup(
name = "test_library",
Behalten wir die Namen der drei `` `test_library``` bei, die in erscheinen. Ich war hier süchtig danach.
Erstellen Sie auf der c ++ - Seite eine Klasse namens `TestClass```. Nennen Sie dies von Python über Cython. Der Einfachheit halber verfügt TestClass nur über einen Konstruktor und eine Methode namens
test_function1 ()
``.
Lassen Sie uns zu diesem Zeitpunkt den Namespace ordnungsgemäß anhängen. Ich bin mir nicht sicher warum, aber dies ist bequemer bei der Konvertierung in Cython. Hier lautet der Namespace "my_library".
test.h
namespace my_library
{
class TestClass{
public:
TestClass();
void test_function1();
};
} // namespace my_library
Schreiben Sie den Inhalt der im Header definierten Funktion. `test_function1 ()`
ist nur eine zu druckende Funktion.
test.cpp
#include <iostream>
#include "test.h"
using namespace std;
namespace my_library{
TestClass::TestClass(){};
void TestClass::test_function1(){
cout << "printed from cpp function" << endl;
}
}
Wie Sie in setup.py sehen können, ist `test_library.pyx``` die Haupt-Cython-Datei. Enthält unten
`library_cython.pyx```.
test_library.pyx
import cython
cimport cython
include "library_cython.pyx"
def test():
return TestClassCython()
Die `` `pxd```-Datei ist wie eine Definitionsdatei zum Übergeben der erforderlichen Informationen an test_library.pyx aus c ++. Jetzt müssen wir wirklich neu schreiben, was im c ++ - Header in Form von Cython definiert wurde.
test_library.pxd
cdef extern from "../my_library/test.h" namespace "my_library":
cdef cppclass TestClass:
TestClass()
void test_function1()
In dieser `` `library_cython.pyx``` definieren wir die Python (Cython?) - Klasse, die tatsächlich auf der Python-Seite aufgerufen wird. Das erste Rätsel besteht darin, den Zeiger der in c ++ definierten Klasse als Mitgliedsvariable der Klasse beizubehalten. Der Konstruktor erstellt eine Klasse auf der c ++ - Seite und übergibt ihre Adresse an diese Mitgliedsvariable ptr. Der Destruktor löscht diesen ptr mit del.
Außerdem ruft die Methode test_function1_cython () die intern auf der c ++ - Seite definierte Methode auf, indem sie auf ptr.test_function1 () gesetzt wird.
library_cython.pyx
import cython
cimport cython
cdef class TestClassCython:
cdef TestClass* ptr
def __cinit__(self):
self.ptr = new TestClass()
def __deadaloc(self):
del self.ptr
def test_function1_cython(self):
self.ptr.test_function1()
Wenn das oben genannte fertig ist,
python setup.py install
Wird besorgt. Wenn Sie es erfolgreich erstellen können, geben Sie den Python-Interpreter und ein
Python 3.6.7 (default, Nov 16 2019, 21:57:19)
[GCC 4.2.1 Compatible Apple LLVM 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import test_library
>>> a = test_library.test()
>>> a.test_function1_cython()
printed from cpp function
>>>
Ich würde mich freuen, wenn ich das könnte.
Also habe ich mit cython versucht, eine in c ++ geschriebene Klasse aus Python über eine Bibliothek aufzurufen. Dies ist nur der Anfang, und die Abhängigkeiten können verwirrend werden, beispielsweise wenn eine Bibliothek verwendet wird, die mit c ++ kompiliert werden muss, aber ich möchte für einen etwas dunkleren Fall erneut schreiben.
Wenn Sie es hilfreich finden, freuen wir uns über Ihre Likes und Kommentare! !!
Ende.
Recommended Posts