Tutoriel "Cython" pour rendre Python explosif: Passez l'objet de classe C ++ à l'objet de classe côté Python. Partie 2

Aperçu

Je veux faire du code écrit en C ++ une bibliothèque qui puisse être appelée en Python. Cependant, il y avait un grand mur appelé Cython.

Ceci est un tutoriel "Cython" qui rend Python explosif: Passez un objet de classe C ++ à un objet de classe côté Python. C'est une continuation de cela ①.

Le code est répertorié dans "github here", veuillez donc y jeter un œil.

La dernière fois, j'ai expliqué comment passer le type déclaré en C ++ au côté Python lors de la conversion d'une bibliothèque écrite en C ++ en Cython afin qu'elle puisse être utilisée à partir de Python.

Il s'est avéré que si vous passez int ou double lui-même, ou un vecteur qui les a comme éléments, il sera converti en un type approprié du côté Python.

Cette fois, je vais vous expliquer comment renvoyer un objet d'une classe définie par vous-même en code C ++ du côté Python.

Explication de la situation

J'ai créé un nouveau TestClass2 '' comme celui-ci pour les tests. La configuration est telle que TestClass1 a l'objet `` TestClass2 comme propriété. Afin de recevoir cette propriété, préparez un constructeur qui reçoit getter '' et setter '', TestClass2.

cpp_library/TestClass2.h


namespace my_library
{
class TestClass2{
    private:
        int property_int;
    public:
        TestClass2(){};

};    
} // namespace my_library

cpp_library/TestClass2.cpp



cpp_library/TestClass1.h


#pragma once
#include <gmp.h>
#include <vector>
#include "TestClass2.h"

using namespace std;

namespace my_library
{
class TestClass1{
    private:
        TestClass2 property_test_class2;
    public:
        //réduction
        TestClass1(TestClass2 test_class2);
        TestClass2 get_property_test_class2();
};    
} // namespace my_library

cpp_library/TestClass1.cpp


//réduction
TestClass1::TestClass1(){
    this->property_test_class2 = TestClass2();
}

TestClass1::TestClass1(TestClass2 test_class2){
    this->property_test_class2 = test_class2;
}

TestClass2 TestClass1::get_property_test_class2(){
    return this->property_test_class2;
}

void TestClass1::set_property_test_class2(TestClass2 test_class2){
    this->property_test_class2 = test_class2;
}

Comment recevoir TestClass2 en Python?

Définissez une classe wrapper pour Pyhton côté Cython et transmettez-lui.

La mise en œuvre ressemble à ceci.

testclass2cython Est testclass2C'est une classe wrapper pour passer à python correspondant à.

cython/test_class2.pxd


cdef extern from "../cpp_library/TestClass2.h" namespace "my_library":
    cdef cppclass TestClass2:
        TestClass2()

cython/test_class2.pyx


cdef class TestClass2Cython:
    cdef TestClass2* ptr

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

    def __deadaloc(self):
        del self.ptr

cython/test_class1.pxd


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

from test_class2 cimport *

cdef extern from "../cpp_library/TestClass1.h" namespace "my_library":
    cdef cppclass TestClass1:
        TestClass1()
        TestClass1(TestClass2 test_class2)
        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)

        void set_property_test_class2(TestClass2 test_class2)
        TestClass2 get_property_test_class2()

L'important ici est

Ici, test_class2.ptr``` est défini dans test_class2.pyx comme cdef TestClass2 * ptr '', et self.ptr [0] est un objet de classe C ++. Signifie la substance de. Puisque get_property_test_class2 () du côté C ++ a renvoyé la substance de l'objet de classe de TestClass2, il était nécessaire de le définir comme self.ptr [0] ``.

cython/test_class2.pyx


    def get_property_test_class2(self):
        cdef:
            TestClass2 cpp_test_class2
        
        test_class2 = TestClass2Cython()
        cpp_test_class2 = self.ptr.get_property_test_class2()
        test_class2.ptr[0] = cpp_test_class2
        return test_class2

Comme d'habitude, après la compilation avec python setup.py install```

(myenv) root@e96f489c2395:/from_local# 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
>>> test = my_library.test()
>>> test.get_property_test_class2()
<my_library.TestClass2Cython object at 0x7f776003d240>

Vous pouvez voir que le TestClass2 '' du côté C ++ est passé au TestClass2Cython '' et peut être reconnu par le côté Python.

Résumé

Pour les objets de la classe définie du côté C ++, il a été constaté qu'il est nécessaire de définir la classe réceptrice du côté Cython et de convertir la valeur de retour de la fonction vers ce type et de la renvoyer.

C'est naturel de dire ça, mais c'est étonnamment difficile, alors j'espère que ça aide.

Ensuite, je voudrais expliquer comment passer un objet de classe côté Python vers C ++ via Cython, contrairement à cette fois.

Cette fois par ici.

fin.

Recommended Posts

Tutoriel "Cython" pour rendre Python explosif: Passez l'objet de classe C ++ à l'objet de classe côté Python. Partie 2
Tutoriel "Cython" pour rendre Python explosif: Passez un objet de classe C ++ à un objet de classe côté Python. Partie ①
Tutoriel "Cython" pour rendre Python explosif: Lorsqu'une fonction côté C ++ a une surcharge.
Tutoriel "Cython" qui rend Python explosif: lorsque le code C ++ dépend de la bibliothèque. Préparation
Tutoriel "Cython" qui rend Python explosif: Gérer le passage de fonctions côté C ++ par référence.
Tutoriel "Cython" qui rend Python explosif: lorsque le code C ++ dépend de la bibliothèque. Écrivez setup.py.
Tutoriel "Cython" qui rend Python explosif: lorsque le code C ++ dépend de la bibliothèque. Tout d'abord, CMake.
Tutoriel "Cython" pour rendre Python explosif: configuration de base
Tutoriel "Cython" pour rendre Python explosif: Comment analyser la classe Enum définie en code C ++ vers Enum en Python.
Faire un point d'arrêt sur la couche c avec python
Transmettez les données OpenCV de la bibliothèque C ++ d'origine à Python
Introduction à Python Hands On Partie 1
[Python + heroku] De l'état sans Python à l'affichage de quelque chose avec heroku (Partie 1)
[Python + heroku] De l'état sans Python à l'affichage de quelque chose avec heroku (partie 2)
[Python] Comment rendre une classe itérable
Essayez de porter le programme «Programmation informatique numérique FORTRAN77» vers C et Python (partie 1)
Essayez de porter le programme "FORTRAN77 Numerical Computing Programming" vers C et Python (partie 3)
Essayez de porter le programme "FORTRAN77 Numerical Computing Programming" vers C et Python (partie 2)
Extension Python C / C ++: transmettre une partie des données à Python en tant que np.array (set stride)
Comment utiliser la bibliothèque C en Python
Essayez de résoudre le problème de l'héritage de classe Python
Introduction à Python avec Atom (en route)
Je veux créer du code C ++ à partir de code Python!
Comment passer des arguments lors de l'appel d'un script python depuis Blender sur la ligne de commande
Réfléchissez à la programmation de Python sur votre iPad
Essayez de créer un module Python en langage C
Étapes pour installer le dernier Python sur votre Mac
Comment faire un test unitaire Part.2 Conception de classe pour les tests
Lisez le fichier xml en vous référant au didacticiel Python
Convertir / renvoyer des objets de classe au format JSON en Python
J'ai senti que j'avais porté le code Python en C ++ 98.
Comment profiter de Python sur Android !! Programmation en déplacement !!
Ne passez pas self à ProcessPoolExecutor en classe
[C / C ++] Passez la valeur calculée en C / C ++ à une fonction python pour exécuter le processus et utilisez cette valeur en C / C ++.
J'ai essayé de créer un générateur qui génère une classe conteneur C # à partir de CSV avec Python