"Cython" -Tutorial, um Python explosiv zu machen: Übergeben Sie ein C ++ - Klassenobjekt an ein Klassenobjekt auf der Python-Seite. Teil ①

Überblick

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 ein "Cython" -Tutorial, das Python explosiv macht: Wie man setup.py schreibt, wenn C ++ - Code von der Bibliothek abhängt. Es wird eine Fortsetzung von sein.

Der Code ist unter "github hier" aufgeführt. Schauen Sie also bitte vorbei.

Bis zum letzten Mal habe ich erklärt, wie setup.py geschrieben wird, um C ++ - Code Cython zu erstellen, wenn dies von der Bibliothek abhängt. Die einzige Funktion auf der C ++ - Seite, die zu diesem Zeitpunkt verwendet wurde, war der void-Typ. Ich denke jedoch natürlich, dass Funktionen häufig Funktionen schreiben, die Werte eines bestimmten Typs zurückgeben, anstatt void zu verwenden. Dieses Mal werde ich erklären, wie eine Funktion, die einen Typ auf der C ++ - Seite anstelle eines ungültigen Typs zurückgibt, in Cython erstellt und an die Python-Seite übergeben wird. Wenn Sie dies verstehen, können Sie noch viel mehr tun. Schauen Sie also bitte vorbei.

Wenn Sie Cython zum Umschließen einer C ++ - Bibliothek zur Verwendung in Python verwenden, analysiert die Python-Seite die C ++ - Klassendefinition nicht automatisch. Daher müssen Sie die Klasse für Python auf der Cython-Seite richtig definieren und mit der C ++ - Seite verbinden.

Es ist einfach zu schreiben, wenn man sich erst einmal daran gewöhnt hat, aber zuerst ist es schwer zu wissen, was zu tun ist, also werde ich das erklären.

Situationserklärung

Ich möchte int oder double übergeben.

Schreiben Sie als Beispiel `test_sum```, das int zurückgibt, und` test_sum_double```, das auf der C ++ - Seite double zurückgibt.

cpp_library/TestClass1.h


#include <gmp.h>

namespace my_library
{
class TestClass1{
    public:
        TestClass1();
        void test_function1();
        static void gmp_print_test();
        static int test_sum(int x, int y);
        static double test_sum_double(double x, double y);
};    
} // namespace my_library

cpp_library/TestClass1.cpp


#include <iostream>
#include "TestClass1.h"
using namespace std;

namespace my_library{

TestClass1::TestClass1(){};
void TestClass1::test_function1(){
    cout << "printed from cpp function" << endl;
}
void TestClass1::gmp_print_test(){
    mpz_t test;
    mpz_init(test);
    mpz_set_ui(test, 1);
    gmp_printf("print : %Zd \n", test);
}

int TestClass1::test_sum(int x, int y){
    return x+y;
}

double TestClass1::test_sum_double(double x, double y){
    return x+y;
}

}

Zu diesem Zeitpunkt sieht der Cython-Code folgendermaßen aus:

cython/test_class1.pxd


cdef extern from "../cpp_library/TestClass1.h" namespace "my_library":
    cdef cppclass TestClass1:
        TestClass1()
        void test_function1()
        void gmp_print_test()
        int test_sum(int x, int y)
        double test_sum_double(double x, double y)

cython/test_class1.pyx


import cython
cimport cython

cdef class TestClass1Cython:
    cdef TestClass1* ptr

    def __cinit__(self):
        self.ptr = new TestClass1()

    def __deadaloc(self):
        del self.ptr

    def test_function1_cython(self):
        self.ptr.test_function1()
    
    @staticmethod
    def gmp_print_test():
        cdef TestClass1 testclass1
        testclass1.gmp_print_test()

    @staticmethod
    def test_sum(int x, int y):
        cdef TestClass1 testclass1
        return testclass1.test_sum(x, y)

    @staticmethod
    def test_sum_double(float x, float y):
        cdef TestClass1 testclass1
        return testclass1.test_sum_double(x, y)

Ich möchte einen Vektor übergeben, der int und double enthält.

Angenommen, Sie haben eine C ++ - Implementierung, die den Vektor wie folgt zurückgibt: Es ist nur eine Testfunktion, die eine Liste erstellt und ein konstantes Vielfaches davon zurückgibt. Schreiben Sie nur den geänderten Teil der Klasse. (Da die Implementierung für das Vektormuster identisch ist, werde ich sie weglassen.)

cpp_library/TestClass1.h


static vector<int> test_vector_int(vector<int> x, int y);

cpp_library/TestClass.cpp



vector<int> TestClass1::test_vector_int(vector<int> x, int y){
    vector<int> result;
    result.resize(x.size());
    for(int i=0; i<x.size(); i++){
        result[i] = x[i]*y;
    }

    return result;
}

cython/test_class1.pxd


from libcpp.vector cimport vector	
from libcpp.string cimport string

cdef extern from "../cpp_library/TestClass1.h" namespace "my_library":
    cdef cppclass TestClass1:
        TestClass1()
        void test_function1()
        void gmp_print_test()
        int test_sum(int x, int y)
        double test_sum_double(double x, double y)
        vector[int] test_vector_int(vector[int] x, int y)

Das obige `von libcpp.vector cimport vector erkennt den vector `auf der C ++ - Seite, so dass auf der Cython-Seite nicht viel zu tun ist. Es kann auf die gleiche Weise implementiert werden wie eine Funktion, die int oder double früher zurückgibt.

cython/test_class1.pyx


    @staticmethod
    def test_vector_int(list x, int y):
        cdef TestClass1 testclass1
        return testclass1.test_vector_int(x,y)

Wenn Sie tatsächlich `` `python setup.py install``` ausführen, können Sie bestätigen, dass die Kompilierung erfolgreich ist und diese Funktionen von der Python-Seite aufgerufen werden können.

(myenv) root@e96f489c2395:/from_local/cython_practice# python 
Python 3.6.3 (default, Jan 30 2020, 06:37:54) 
[GCC 7.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import my_library
>>> my_library.TestClass1Cython.test_vector_int([1,2,3], 3)
[3, 6, 9]

Ich möchte eine benutzerdefinierte Klasse in einer C ++ - Bibliothek übergeben.

Als nächstes werde ich es in einem Artikel schreiben.

Zusammenfassung

Dieses Mal erklärte ich, dass beim Konvertieren einer in C ++ geschriebenen Bibliothek nach Cython, damit sie von Python aus verwendet werden kann, der in C ++ deklarierte Typ an die Python-Seite übergeben wird.

Es stellte sich heraus, dass wenn Sie int oder double selbst oder einen Vektor übergeben, der sie als Elemente enthält, dieser auf der Python-Seite in einen geeigneten Typ konvertiert wird. Es kann überraschend einfach implementiert werden.

Das nächste Mal werde ich erklären, wie ein Objekt einer von Ihnen in C ++ - Code definierten Klasse an die Python-Seite zurückgegeben wird. Es ist etwas komplizierter als int, double und vector mit ihnen als Elementen, aber es gibt viele Situationen wie diese in tatsächlichen Programmen, also schauen Sie bitte.

Diesmal hier.

Ende.

Recommended Posts

"Cython" -Tutorial, um Python explosiv zu machen: Übergeben Sie ein C ++ - Klassenobjekt an ein Klassenobjekt auf der Python-Seite. Teil ①
"Cython" -Tutorial, um Python explosiv zu machen: Übergeben Sie das C ++ - Klassenobjekt an das Klassenobjekt auf der Python-Seite. Teil 2
"Cython" -Tutorial, um Python explosiv zu machen: Wenn eine Funktion auf der C ++ - Seite überlastet ist.
"Cython" -Tutorial, das Python explosiv macht: Handhabung, wenn Funktionen auf der C ++ - Seite als Referenz übergeben werden.
"Cython" -Tutorial, das Python explosiv macht: Wenn C ++ - Code von der Bibliothek abhängt. Vorbereitung
"Cython" -Tutorial, das Python explosiv macht: Wenn C ++ - Code von der Bibliothek abhängt. Schreiben Sie setup.py.
"Cython" -Tutorial, um Python explosiv zu machen: So analysieren Sie die in C ++ - Code definierte Enum-Klasse mit Enum in Python.
"Cython" -Tutorial, das Python explosiv macht: Wenn C ++ - Code von der Bibliothek abhängt. Zuallererst CMake.
"Cython" Tutorial, um Python explosiv zu machen: Grundkonfiguration
Machen Sie mit Python einen Haltepunkt auf der c-Ebene
[Python] Wie man eine Klasse iterierbar macht
Versuchen Sie, ein Python-Modul in C-Sprache zu erstellen
[C / C ++] Übergeben Sie den in C / C ++ berechneten Wert an eine Python-Funktion, um den Prozess auszuführen, und verwenden Sie diesen Wert in C / C ++.
Verwendung der Methode __call__ in der Python-Klasse
Ich habe versucht, einen Generator zu erstellen, der mit Python eine C # -Containerklasse aus CSV generiert
Übergeben Sie die OpenCV-Daten der ursprünglichen C ++ - Bibliothek an Python
[Python] Ich habe versucht, mit argparse ein einfaches Programm zu erstellen, das in der Befehlszeile funktioniert
[Python + Heroku] Vom Zustand ohne Python zur Anzeige von etwas mit Heroku (Teil 2)
Übergeben Sie die Liste von Python an C ++ als Referenz in pybind11
Einführung in Python Hands On Teil 1
[Python] Machen Sie die Funktion zu einer Lambda-Funktion
Umgang mit "^ [[A ^ [[B ^ [[C ^ [[D"]] beim Drücken der Richtungstaste beim Ausführen von Python auf dem Mac
[Python] Ein Fortschrittsbalken auf dem Terminal
[19.11.2015] So registrieren Sie einen Dienst lokal mit dem Python SDK bei naoqi os
So übergeben Sie das Ergebnis der Ausführung eines Shell-Befehls in einer Liste in Python
Versuchen Sie, das Programm "FORTRAN77 Numerical Computing Programming" auf C und Python zu portieren (Teil 1).
Machen Sie ein Thermometer mit Raspberry Pi und machen Sie es im Browser Teil 3 sichtbar
[Python] Erstellt eine Klasse, um mit pyaudio Sinuswellen im Hintergrund zu spielen
Versuchen Sie, das Programm "FORTRAN77 Numerical Computing Programming" auf C und Python zu portieren (Teil 3).
[Python] Smasher hat versucht, den Video-Ladevorgang mithilfe eines Generators zu einer Funktion zu machen
Versuchen Sie, das Programm "FORTRAN77 Numerical Computing Programming" auf C und Python zu portieren (Teil 2).
Konvertieren der cURL-API in ein Python-Skript (mithilfe des IBM Cloud-Objektspeichers)
C-Sprache zum Sehen und Erinnern Teil 3 Rufen Sie die C-Sprache aus Python auf (Argument) c = a + b
Python C / C ++ - Erweiterung: Übergeben Sie einen Teil der Daten als np.array an Python (Schritt setzen)
Ein Memo, das ein Tutorial zum Ausführen von Python auf Heroku erstellt hat
Verwendung der C-Bibliothek in Python
Versuchen Sie, das Problem der Python-Klassenvererbung zu lösen
Hinweise zum Anpassen der Diktatlistenklasse
Ich möchte ein Spiel mit Python machen
Kopieren Sie die Liste in Python
So generieren Sie ein Python-Objekt aus JSON
Versuchen Sie, in Python einen "Entschlüsselungs" -Code zu erstellen
Python: Bereiten Sie einen Serializer für die Klasseninstanz vor:
Einführung in Python mit Atom (unterwegs)
Speichern Sie das Objekt in einer Datei mit pickle
Versuchen Sie, mit Python eine Diedergruppe zu bilden
Python Amateur versucht die Liste zusammenzufassen ②
Ich möchte C ++ - Code aus Python-Code erstellen!
[Python] Wirf eine Nachricht an den Slack-Kanal
Ich habe ein wenig über die Klasse recherchiert
Lark grundlegende Erklärung (machen Sie einen Shell-ähnlichen Kerl mit Python, Lark)
[Python] Sie können ein Objekt mithilfe des Pickle-Moduls in einer Datei speichern.
Übergeben von Argumenten beim Aufrufen von Python-Skripten über Blender in der Befehlszeile
Machen wir einen Sprung in die Fertigungsindustrie, indem wir zusätzlich zu Python das Web nutzen
Nehmen Sie eine Instanz einer Python-Ausnahmeklasse nicht direkt als Argument für die Ausnahmeklasse!