7
votes

Dépendances de module croisée à Boost Python

Supposons que j'ai deux modules de python Boost définis comme suit. Module A:

Traceback (most recent call last):
  File "C:\bladiebla\script.py", line 8, in <module>
    obj2.func(obj1)
ArgumentError: Python argument types in
AnotherClass.func(AnotherClass, SomeClass)
did not match C++ signature:
func(class AnotherClass {lvalue}, class SomeClass)


0 commentaires

3 Réponses :


0
votes

En fonction de votre dernier message d'erreur et de votre message d'erreur mis à jour dans votre question, je pense que le problème peut être parce que votre boost_python_module code> peut être incorrect (sur la base de ce que j'ai vu dans d'autres exemples d'utilisation ). Essayez quelque chose comme ça et voyez s'il aide:

Module A: P>

class AnotherClass {
public:
    AnotherClass() {}
    ~AnotherClass() {}
    void func(SomeClass& sp) {}
};
BOOST_PYTHON_MODULE(B)
{   boost::python::class_<AnotherClass>("AnotherClass")
        .def("func", &AnotherClass::func)
    ;
}


8 commentaires

Bonjour, merci beaucoup pour vos commentaires. Cependant, j'aimerais résoudre ce problème pour deux classes qui n'ont pas de relation d'héritage. Par exemple, vous pouvez imaginer que "soméclasse" est en fait une classe "triangle" et que "une autreclass" est la classe "polygone". Je ne veux certainement pas que le polygone hérite du triangle, car il n'a pas de sens d'un point de vue OO. Alors, comment puis-je avoir deux classes dans différents modules qui n'héritez pas les uns des autres, mais qui se sont utilisés par Python, comme dans mon exemple original?


Func () veut un Someclass argument. Si vous voulez transmettre quelque chose de différent, comme autreclass , vous pouvez le faire sans Fabrication autreclass hériter à partir de SOMECLAS En ajoutant un constructeur à Someclass qui prend un autreclass comme argument. Sinon, vous pouvez simplement écrire quelque chose qui acceptait un argument autreClass et renvoyé un Someclass instance, mais il faudrait l'appeler explicitement. Si vous ne pouvez pas faire quelque chose comme ça, je pense que vous êtes coincé - Qu'est-ce que Func () est censé faire de toute façon, s'ils ont passé une classe arbitraire, cela ne sait rien?


Oui, je comprends que, mais je ne veux pas passer quelque chose de différent à cette fonction, seulement un argument de type soméclasse. Dans l'exemple du script Python, mon obj1 est de type A.Someclass. Il n'est pas liée à B.Anotherclass. "FUNC" dans B.Anotherclass doit accepter les paramètres de type A.Someclass, tels que obj1.


Si FUNC () Accepte autreClass arguments, modifier sa déclaration dans Classe autreclass dans le module B sur VOID FUNC (autreClass & SP) - C'est sa "signature C ++". Ensuite, le obj2.func (obj1) L'appel devrait être ok.


PS, la seule raison pour laquelle vous pouvez vous éloigner avec la modification de la signature de Func () SIMP (CODE> FUNC () Comme je l'ai suggéré, c'est que cela ne fait rien avec son argument depuis son défini (Inline ) Pour être une fonction vide, {} , dans votre code exemple. Si cela a accédé à son argument et essayé de faire quelque chose avec elle, le changement ne fonctionnerait probablement pas à moins que le code ne puisse vraiment gérer un objet de type autreclass .


Je pense que vous avez mal compris ce que j'essaie de faire. Je ne veux pas passer autre chose qu'un argument de type Someclass à Func (). Dans le script Python, obj1 est de type soméclasse. Je devrais pouvoir le transmettre à Func () en tant que paramètre, comme je le fais dans la dernière ligne du script. Le noyau de ce problème est que le module B n'est pas au courant des symboles exportés vers Python par module A. Je recherche un moyen de dire le module B que la somclasse de classe a été exposée à Python par le module A.


Ok, mais je ne pense pas que le problème ait besoin de "dire le module B que la somclasse de classe a été exposée à Python par module A". Si vous regardez de très près les messages d'erreur, il est indiqué que la signature FUNC () 'SIMC (CODE> FUNC () nécessite un SOMOCLASS * Deuxième argument qui est un pointeur > à un Someclass instance - mais on dirait que cela pense que vous essayez de passer une instance par valeur via le obj2.func (obj1) déclaration.


Vous avez raison. J'ai collé le mauvais message d'erreur dans la question lorsque je testais s'il était peut-être fonctionné avec des pointeurs à la place. Je mets le bon message d'erreur dans l'exemple. C'est l'erreur que je reçois lors de l'exécution du script.



7
votes

Je viens de commencer à jouer avec Boost.python et avait le même problème.

Découvrez la section 6 du document suivant:

http://www.boost.org/doc/libs/1_47_0 /Libs/python/doc/building.html

6.1 - Le binaire dynamique

La bibliothèque contient un registre de conversion de type. Parce qu'un registre est partagé parmi tous les modules d'extension, des instances d'une classe exposée à Python dans un module d'extension chargé de manière dynamique peuvent être transmises à des fonctions exposées dans un autre module de ce type . .

J'utilisais le binaire statique et j'ai eu le même type d'erreur que vous receviez. Une fois que j'ai changé vers le binaire dynamique, il a compilé et couru bien.


0 commentaires

-1
votes

J'ai eu un problème similaire et je l'ai résolu en importateur de module A du module B utilisant boost :: python :: import () fonction.


0 commentaires