IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

[C++ et Python] Passer un objet par référence à un script Python


Sujet :

C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 55
    Points : 43
    Points
    43
    Par défaut [C++ et Python] Passer un objet par référence à un script Python
    Bien le bonjour !

    J'ai un petit problème. Je bosse sur l'utilisation de l'interpréteur Python dans un programme C++ et je souhaite passer une instance d'un objet C++ à un script Python pour l'utiliser et le modifier dans ce dernier.

    Je n'utilise que l'API C de Python et j'avoue ne pas y parvenir. J'ai ouïe dire à droite à gauche qu'une solution existait avec SWIG mais après avoir regardé de plus près je ne suis pas sur que SWIG puisse réellement résoudre ce problème.

    Si quelqu'un connait une méthode efficace avec l'API C de Python ou peut me renseigner plus précisément sur SWIG, ce serait super.

  2. #2
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 38
    Points : 31
    Points
    31
    Par défaut
    Salut BigzYeah,

    J'ai fait du SWIG dans mon projet actuel parce que je devais wrapper du code C++ en Python pour l'utiliser dans les deux langages.

    Et il m'a servi à résoudre mon problème de références, car Python ne gère que les pointeurs. Il m'a suffit de faire des typemap pour faire la correspondance entre les langages.

    Si ça c'est ce que tu veux, tu peux peut-être poster un exemple de ce que tu essaies de faire, et on pourra essayer d'utiliser SWIG pour résoudre ton souci

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 55
    Points : 43
    Points
    43
    Par défaut
    Fort bien, merci de ton aide =)

    Dans un premier temps, prenons un exemple simple de ce que je souhaite.

    D'un côté nous avons l'application C++ qui va se charger d'appeler une méthode contenu dans un script Python. Lors de cette appel, le programme C++ va donner en paramètre une instance d'une chaîne de caractère.

    De la sorte :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    Py_Initialize();
     
    PyObject *pName, *pModule, *pFunc;
    PyObject *pArgs, *pValue;
     
    String maStringCPP = "Je suis une string super cool !"
     
    pName = PyString_FromString("module"); 
    pModule = PyImport_Import(pName);
     
    pFunc = PyObject_GetAttrString(pModule, "modifier");
     
    pArgs = PyTuple_New(1);
    pValue = PyString_FromString(maStringCPP);
    PyTuple_SetItem(pArgs, 0, pValue);
     
    // Ici on appel la méthode modifier en donnant en paramète la string
    PyObject_CallObject(pFunc, pArgs);
     
    Py_Finalize();
    Dans le script Python, il y aura donc une méthode modifier() qui prendra en paramètre une string et qui la modifiera, de la sorte :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    def modifier(maStringPython):
        maStringPython = "String modifiée"
    Le but recherché étant que la modification de la chaîne faite dans le script Python modifie la valeur de la chaîne se trouvant dans le programme C++.

    Le présent code ne fonctionne bien évidemment pas. Ici la string C++ est transformée en string python. Ces objets étant imutables en Python, la modification de maStringPython n'influe en rien sur maStringCPP. Pour parer à ce problème d'imutabiltié, j'ai essayé d'utiliser une liste mais une exception est levée lors de l'appel de la méthode.

    Ce que je cherche est en soit assez simple. Je veux pouvoir passer maStringCPP au script Python soit par référence, soit comme pointeur pour pouvoir travailler sur l'objet et non sa valeur.

    La finalité étant d'utiliser ce principe pour passer un objet bien plus complexe qu'une string.

  4. #4
    Membre éprouvé
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2009
    Messages
    552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2009
    Messages : 552
    Points : 1 060
    Points
    1 060
    Par défaut
    Bonsoir,

    Pour SWIG, je te conseille de lire la documentation. Ca fait un peu peur, vu la taille, mais c'est pas mal organisé.

    http://www.swig.org/Doc1.3/Python.html

    Grosso merdo, le principe et le suivant :

    Tu as tes codes en C/C++ (les headers surtout), tu écris un fichier d'interface (.i) qui reprend les informations des headers (.h) auxquelles tu ajoutes des instructions (du style : ce pointeur en retour c'est un new; ou la classe est virtuelle pure, etc...)

    A partir de ce .i, swig génère un wrapper (un fichier .cpp) qui permettra de générer ton module.

    swig [-c++] -python mon_module.i

    Ensuite, tu compiles le wrapper en temps que bibliothèque partagée en le liant à ta bibliothèque et à celle de python, tu renommes le résultat en _mon_module.pyd et hop, tu peux l'importer.

    http://www.swig.org/Doc1.3/Python.html#Python_nn10


    Un point particulièrement intéressant réside dans le fait que la stl est déjà décrite de sorte que SWIG génère le wrapper pour les std::string, les std::vector, etc...

    http://www.swig.org/Doc1.3/Python.html#Python_nn52

    Perso, j'avoue que cet outil m'impressionne


    Bonne continuation,

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 55
    Points : 43
    Points
    43
    Par défaut
    Merci de ces explications. Néanmoins, elles me laissent penser que SWIG ne permet qu'un extending de Python plutôt qu'un embedding dans du c++.

    Du moins, de ce que je comprend, SWIG est parfaitement adapté pour qu'un script Python se serve de méthodes C++, mais est il possible de faire l'inverse ?

  6. #6
    Membre éprouvé
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2009
    Messages
    552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2009
    Messages : 552
    Points : 1 060
    Points
    1 060
    Par défaut
    Citation Envoyé par BigzYeah Voir le message
    Merci de ces explications. Néanmoins, elles me laissent penser que SWIG ne permet qu'un extending de Python plutôt qu'un embedding dans du c++.
    Tu penses juste, dans l'autre sens je ne connais pas d'outils à part l'api de bas niveau.

    Je n'ai pas encore eu à le faire, du coup, je te conseille de googleliser "embedding python in c++"

    Bonne continuation

  7. #7
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 55
    Points : 43
    Points
    43
    Par défaut
    Hélas j'ai comme contrainte de ne pas utiliser Boost Python :/

    Je suis convaincu qu'il est possible de le faire avec l'API C de Python mais la démarche m'est encore inconnue.

    J'ai pourtant fait une dose de recherche assez monstrueuse sur le net mais semble t'il que peu de personnes utilise l'API C. A par la documentation, qui est pourtant très complète, il y a pas grand chose d'autre.

    EDIT : Si aucune autre options m'est disponible, je vais essayer de faire du forcing auprès de mon chef de projet pour utiliser Boost. Dans ce cas j'aimerais savoir comment se passe le passage d'instance depuis l'appli C++ jusqu'au script Python. Peut on envoyer un pointeur ? Ou peut on faire un passage par référence ? Y a t'il une conversion entre objet C++ et objet Python à faire manuellement ou Boost se charge de tout ?

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 55
    Points : 43
    Points
    43
    Par défaut
    Petit complément d'information.

    Les objets que je souhaite manipuler entre mon appli C++ et mon script Python sont des objets COM. Plus particulièrement des contrôles ActiveX. Ces contrôles ne seront pas écrit par moi, impossible donc de se baser sur un wrapping de ces objets. A première vu, il semble donc impossible de transformer une instance d'un contrôle activeX en objet Python puisque ces contrôles seront une sorte de type inconnu.

    Néanmoins certains choses sont possibles. Créer une instance d'un contrôle dans l'appli C++ à partir de son CLSID (un truc qui ressemble à ça : {232E456A-87C3-11D1-8BE3-0000F8754DA1}).
    Il m'est aussi possible de créer un instance de ce contrôle dans mon script Python, à l'aide du module comtypes.

    Le soucis étant que je veux le créer dans le C++ et le modifier dans le script Python. C'est donc ce seul transfert de donnée qui m'est important. Est-ce possible de passer au script l'adresse mémoire de l'instance C++ pour l'utiliser dans le script ? J'en doute un peu.

    Si quelqu'un a la moindre idée, proposition ou n'importe quoi, faites vous plaisir (et à moi aussi par la même occasion )

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 55
    Points : 43
    Points
    43
    Par défaut
    Bon, je suis pas encore tout à fait sur d'utiliser boost, même si je vois mal comment faire sans. Toujours est il que je me pose une question au niveau de la compatibilité 32/64 bits. A mon avis ça ne doit pas poser de problème mais je n'en suis pas sur. Si quelqu'un peut m'éclairer à ce sujet.

Discussions similaires

  1. Passer un objet par valeur et non référence
    Par Pynouz dans le forum C#
    Réponses: 2
    Dernier message: 14/01/2011, 09h42
  2. [POO] Modifier attributs d'un objet par référence
    Par justSam dans le forum Langage
    Réponses: 8
    Dernier message: 22/02/2007, 07h58
  3. [debutant]passer un objet par const reference
    Par Battosaiii dans le forum Débuter
    Réponses: 6
    Dernier message: 12/11/2005, 14h39
  4. retour d'objet par référence...
    Par sas dans le forum C++
    Réponses: 15
    Dernier message: 28/05/2005, 17h54
  5. [JACOB] Comment passer un objet par référence à une méthode
    Par zlavock dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 21/03/2005, 18h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo