Tutoriel "Cython" qui rend Python explosif: Gérer le passage de fonctions côté C ++ par référence.

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.

C'est le tutoriel "Cython" qui rend Python explosif: quand une fonction côté C ++ a une surcharge. Ceci est une continuation de.

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

La dernière fois, j'ai expliqué la Cythonisation lorsqu'une fonction côté C ++ est surchargée (lorsque la configuration a le même nom de fonction mais des arguments différents).

Cette fois, je voudrais expliquer comment gérer les fonctions C ++ côté Cython lors du passage par référence au lieu de passer par valeur comme argument. Il n'y a pas grand-chose de nouveau, mais lorsque vous essayez réellement d'écrire Cython, vous êtes souvent ennuyé par les erreurs, alors assurez-vous de le vérifier! !!

Explication de la situation

Je vais vraiment l'essayer.

cpp_library/TestClass1.h


class TestClass1{
    private:
        TestClass2 property_test_class2;
        EnumForTestClass1 group;

    public:
        //~réduction
        static void print_vector(vector<int> &x);
        static void print_vector(vector<double> &x);

La différence avec la dernière fois est que l'argument x de `` `` print_vector est changé de ** par valeur à passé par référence **.

cpp_library/TestClass1.cpp


void TestClass1::print_vector(vector<int> &x){
    for(int i=0; i<x.size(); i++){
        cout << x[i] << " ";
    }
    cout << endl;
}

void TestClass1::print_vector(vector<double> &x){
    for(int i=0; i<x.size(); i++){
        cout << x[i] << " ";
    }
    cout << endl;
}

Quand j'essaye de construire ceci avec python setup.py install '' comme d'habitude, j'obtiens l'erreur suivante:


./cython/my_library.cpp:2414:69: error: cannot bind non-const lvalue reference of type 'std::vector<int>&' to an rvalue of type 'std::vector<int>'
     __pyx_t_1 = __Pyx_void_to_None(__pyx_v_testclass1.print_vector(((std::vector<int> )__pyx_t_4))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 53, __pyx_L1_error)

Le casting doit être soigné, mais je me fâche lorsqu'il s'agit de passer par référence.

Donc, comme solution

Créez l'entité sur place, pas le casting.

Qu'est-ce que ça veut dire?

cython/test_class1.pyx


    @staticmethod
    def print_vector(list x):
        cdef:
            TestClass1 testclass1
            vector[int] vec_int
            vector[double] vec_double
        
        if isinstance(x[0], int):
            vec_int.resize(len(x))
            for i in range(len(x)):
                vec_int[i] = <int>x[i]
            return testclass1.print_vector(vec_int)
        elif isinstance(x[0], float):
            vec_double.resize(len(x))
            for i in range(len(x)):
                vec_double[i] = <double>x[i]
            return testclass1.print_vector(vec_double)
        else:
            raise Exception('TypeError')

ça ira. Maintenant, avec `cdef```, créez` vector [int] ```et `` vecteur [double] `ʻà la volée et passez-le à la fonction. Peut-être que l'erreur que je viens de recevoir est passée par référence, mais je ne sais pas si elle existe vraiment! Ne t'inquiète pas! !! !! J'interprète que c'était une erreur.

Par conséquent, il est bon de préparer la substance et de la rassurer.

Ensuite, comme d'habitude, python setup.py install` '' passera la construction.

En faisant cela, en écrivant le code de test comme suit,

test.py


import my_library as myl

if __name__ == "__main__":

    cl1 = myl.test()
    x = [1,2,3]
    y = [1.1, 2.2, 3.3]
    cl1.print_vector(x)
    cl1.print_vector(y)

J'ai pu appeler la fonction correctement.

(myenv) root@e96f489c2395:/from_local/cython_practice# python test.py 
1 2 3 
1.1 2.2 3.3 

Résumé

Cette fois, j'ai expliqué comment gérer la fonction côté C ++ lors du passage par référence au lieu de passer par valeur en tant qu'argument côté Cython.

Cette fois-ci.

fin.

Recommended Posts

Tutoriel "Cython" qui rend Python explosif: Gérer le passage de fonctions côté C ++ par référence.
Tutoriel "Cython" pour rendre Python explosif: Lorsqu'une fonction côté C ++ a une surcharge.
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: Passez l'objet de classe C ++ à l'objet de classe côté Python. Partie 2
Tutoriel "Cython" qui rend Python explosif: lorsque le code C ++ dépend de la bibliothèque. Préparation
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
[Python] Assurez-vous que la fonction reçue est une fonction définie par l'utilisateur
Utilisons AWS Lambda pour créer un mécanisme pour notifier Slack lorsque la valeur surveillée par CloudWatch est dépassée sur Python
[Python] Faire de la fonction une fonction lambda
Extension de Python par C ou C ++ (lorsqu'il y a plusieurs arguments, lors du passage d'une liste du côté Python)
python Comment notifier automatiquement par téléphone lorsque le système tombe en panne
Comment gérer "^ [[A ^ [[B ^ [[C ^ [[D"]] en appuyant sur la touche de direction lors de l'exécution de python sur mac
Une histoire bloquée lors de la tentative de mise à niveau de la version Python avec GCE
Faisons un saut dans l'industrie manufacturière en utilisant le Web en plus de Python
Ajouter une fonction pour indiquer la météo d'aujourd'hui au bot slack (fabriqué par python)
Lisez le fichier xml en vous référant au didacticiel Python
[Python] Comment appeler une fonction de c depuis python (édition ctypes)
Django super introduction par les débutants Python! Partie 6 J'ai essayé d'implémenter la fonction de connexion
[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 une API RESTful en connectant l'API rapide du framework Python explosif à MySQL.
Notification Slack lorsqu'un mot spécifique est murmuré sur Twitter en utilisant Heroku avec python
Solution de contournement pour sys.argv non transmise lors de l'exécution d'un script Python avec uniquement le nom de fichier sur Python2.7 sous Windows
Enfin ... Créez un contrôleur radio en utilisant python sur Raspberry Pi 3! (Lorsque l'aimant est rapproché, le moteur se déplace et s'arrête automatiquement)
[Python] Comment créer une liste de chaînes de caractères caractère par caractère
[python] Remarques lors de la tentative d'utilisation de numpy avec Cython
Lorsque vous souhaitez lancer une commande UNIX sur Python
Écrivez un script dans Shell et Python pour vous avertir dans Slack lorsque le processus est terminé
[Python] J'ai essayé de créer un programme simple qui fonctionne sur la ligne de commande en utilisant argparse
À propos de l'erreur que j'ai rencontrée en essayant d'utiliser Adafruit_DHT à partir de Python sur Raspberry Pi
[Introduction à Python] Comment fractionner une chaîne de caractères avec la fonction split
Est-il facile de synthétiser un médicament sur le marché?
[Python] Temps d'exécution lorsqu'une fonction est saisie dans une valeur de dictionnaire
[Python3] Définition d'un décorateur qui mesure le temps d'exécution d'une fonction
Construire un environnement Python sur Ubuntu (lorsque pip n'était pas la valeur par défaut)
Que faire lorsque le type de valeur est ambigu en Python?
[Python] Une fonction simple pour trouver les coordonnées du centre d'un cercle
Django super introduction par les débutants Python! Partie 3 J'ai essayé d'utiliser la fonction d'héritage de fichier de modèle
Enfin ... Créez un contrôleur radio en utilisant python sur Raspberry Pi 3! (Le moteur se déplace lorsque le bouton est enfoncé)