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! !!
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
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
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.