Augmentation de l’erreur d’exécution Python lors du passage d’un object de type dérivé de python à une fonction C ++ dans l’attente d’un shared_ptr au type de base

J’ai une fonction qui prend un std :: shared_ptr et je veux passer un object de type Derived à cette fonction à partir de python. Voici mes définitions de classe:

struct AbstractBase { virtual void foo() = 0; }; struct Derived : public AbstractBase { virtual void foo(){ std::cout<<"Derived's foo!"<<std::endl; } }; struct Unrelated { void bar(std::shared_ptr base_shared_ptr) { base_shared_ptr->foo(); } }; #endif /* CLASSES_H */ 

Un exemple pur et simple en C ++ fait ce que je veux:

 int main() { std::shared_ptr d(new Derived); Unrelated u; u.bar(d); } 

sortie: Derived's foo!

Voici mon code Boost.Python Wrapper:

 #include  #include "classes.h" BOOST_PYTHON_MODULE(shared_ptr_test) { using namespace boost::python; class_<AbstractBase,std::shared_ptr,boost::noncopyable>("AbstractBase",no_init); class_<Derived,std::shared_ptr,bases,boost::noncopyable>("Derived"); class_<Unrelated,std::shared_ptr,boost::noncopyable>("Unrelated") .def("bar",&Unrelated::bar); } 

Et voici mon test de python simple:

 import shared_ptr_test d=shared_ptr_test.Derived() u=shared_ptr_test.Unrelated() u.bar(d) 

À mon grand désarroi, cela ne fonctionne pas. Cela comstack bien, mais lorsque je lance le script python, j’obtiens cette erreur:

 Traceback (most recent call last): File "test.py", line 5, in  u.bar(d) Boost.Python.ArgumentError: Python argument types in Unrelated.bar(Unrelated, Derived) did not match C++ signature: bar(Unrelated {lvalue}, std::shared_ptr) 

Changer de bar pour prendre un shared_ptr corrige cela, donc je sais qu’en interne Boost.Python gère les objects avec shared_ptr s. Dois-je faire quelque chose de plus pour que Boost.Python réalise qu’il est correct de passer un shared_ptr à une fonction qui attend un shared_ptr ?

Boost.Python doit savoir qu’un pointeur intelligent sur Derived peut être converti en un pointeur intelligent sur AbstractBase . Ceci peut être accompli de l’une des manières suivantes:

  • Utiliser boost::shared_ptr . Boost.Python a du code pour gérer les conversions implicites entre boost::shared_ptr lorsque leur type d’ element_type est hiérarchique.
  • Enregistrez une conversion implicite de std::shared_ptr vers std::shared_ptr via boost::python::implicitly_convertible . std::shared_ptr répond aux exigences de concept pour implicitly_convertible . Il suffit donc d’enregistrer la conversion dans la définition du module:

     implicitly_convertible, // Source std::shared_ptr >(); // Target