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

Interfaçage autre langage Python Discussion :

ctypes, callback fonction et valeur de retour


Sujet :

Interfaçage autre langage Python

  1. #1
    Membre actif
    ctypes, callback fonction et valeur de retour
    J'utilise à partir de Python une librairie compilé à partir de code C.
    J'appelle des fonctions de la librairie et je voudrais récupérer le résultat dans python.

    Voici le code python
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Lib = ct.cdll.LoadLibrary('librairie.so')
    CMPFUNC2 = ct.CFUNCTYPE(None,ct.c_char_p)
    setCallBack = CMPFUNC2(setResult)
    Lib.start(setCallBack)
     
    def setResult(self, Name):
        bestName = Name.decode()
        return bestName

    et la librairie C
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    void start(void (*setResultToTheGUI)(char*))
    {
    ...
    setResultToTheGUI(bestNameToTheGUI);
    ...
    }


    Je voudrais donc récupérer bestName côté python.

  2. #2
    Modérateur

    Salut,

    Citation Envoyé par senacle Voir le message
    Je voudrais donc récupérer bestName côté python.
    Si votre fonction Python "setResult" est appelée, vous récupérez déjà "bestName" côté Python non?
    Pourquoi déclarer 2 paramètres alors que la fonction n'est appelée qu'avec un seul.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre actif
    Citation Envoyé par wiztricks Voir le message

    Pourquoi déclarer 2 paramètres alors que la fonction n'est appelée qu'avec un seul.
    Je n'ai pas mis le code en entier.
    Le premier paramètre "self", c'est parce qu'on est dans une classe.

  4. #4
    Membre actif
    Citation Envoyé par wiztricks Voir le message

    Si votre fonction Python "setResult" est appelée, vous récupérez déjà "bestName" côté Python non?
    C'est bien ce que je croyais...

    Lib.start prend en paramètre la fonction setCallBack, qui "représente" "setResult".

    Et la valeur attendue par "setResult" provient de Lib.start, via setResultToTheGUI(bestNameToTheGUI).

    C'est bien ça ? Pas sûr d'avoir tout compris...

    Si je fais côté Python
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    Lib.start(setCallBack('toto'))

    j'ai
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    toto

    Ca, c'est normal.

    Mais ce que je veux, c'est la valeur qui est renvoyée par calculée dans la fonction start de la librairie C.

  5. #5
    Modérateur

    Citation Envoyé par senacle Voir le message
    Mais ce que je veux, c'est la valeur qui est renvoyée par calculée dans la fonction start de la librairie C.
    Et bien, commencez par respecter les interfaces et poster des informations plus claires!!! Car si j'essaie de vous suivre:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>> def setResult(self, Name):
    ...     bestName = Name.decode()
    ...     return bestName
    ...
    >>> setResult('toto')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: setResult() missing 1 required positional argument: 'Name'
    >>>

    Donc Lib.start(setCallBack('toto')) fait autre chose que ce que vous présentez.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Membre actif
    Citation Envoyé par wiztricks Voir le message

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>> def setResult(self, Name):
    ...     bestName = Name.decode()
    ...     return bestName
    ...
    >>> setResult('toto')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: setResult() missing 1 required positional argument: 'Name'
    >>>

    Pour essayer de reproduire comme vous le faites, vous pouvez retirer le premier paramètre self.

  7. #7
    Membre actif
    Je poste à nouveau le code avec quelques modifications pour essayer de clarifier.

    Voici le code python
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Lib = ct.cdll.LoadLibrary('librairie.so')
    CMPFUNC2 = ct.CFUNCTYPE(None,ct.c_char_p)
    setCallBack = CMPFUNC2(setResult)
    Lib.start(setCallBack)
     
    def setResult(Name):
        bestName = Name.decode()
        return bestName

    et la librairie C
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void start(void (*setResultToTheGUI)(char*))
    {
    ...
    bestNameToTheGUI = 'valeur_de_renvoi';
    setResultToTheGUI(bestNameToTheGUI);
    ...
    }


    Je voudrais donc récupérer bestNameToTheGUI côté python, c'est-à-dire : valeur_de_renvoi

  8. #8
    Modérateur

    Citation Envoyé par senacle Voir le message
    Je voudrais donc récupérer bestNameToTheGUI côté python, c'est-à-dire : valeur_de_renvoi
    Même réponse que précédemment, si la fonction "setResult" est appelée, "valeur_de_renvoi" doit être reçu en paramètre....
    Et comme c'est déjà côté Python, où est le problème?

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #9
    Membre actif
    Citation Envoyé par wiztricks Voir le message
    Même réponse que précédemment, si la fonction "setResult" est appelée, "valeur_de_renvoi" doit être reçu en paramètre....
    Et comme c'est déjà côté Python, où est le problème?

    - W
    Si je fais :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    print(setCallBack)


    J'obtiens
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    <CFunctionType object at 0x7fd6bac8b940>


    Si je fais :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    print(setResult)


    J'obtiens
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    <bound method setResult of <object at 0x7f4f14c61c30>


    Si je fais :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    print(bestNameToTheGUI)


    J'obtiens
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    NameError: global name 'bestNameToTheGUI' is not defined


    C'est sûrement très simple, mais je ne vois pas quelle ligne de code écrire côté Python pour que je puisse avoir ce fameux "valeur_de_renvoi ".
    Dans quoi cette valeur est stockée côté Python ?

  10. #10
    Membre actif
    Citation Envoyé par wiztricks Voir le message
    si la fonction "setResult" est appelée, "valeur_de_renvoi" doit être reçu en paramètre
    La fonction "setResult" n'est pas appelée directement dans le code Python, elle l'est en tant que paramètre de la fonction C.
    C'est là que je ne vois pas comment récupérer la valeur côté Python.

    appel direct qui affiche toto
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    print(setResult('toto'))


    appel en paramètre via la fonction de la librairie C.
    Comment faire ici pour afficher "valeur_de_renvoi" côté Python ?

  11. #11
    Modérateur

    Salut,

    Si je comprends bien on peut virer ctypes et écrire:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    def setResult(Name):
        bestName = Name.decode()
        return bestName
     
    def start(f)
        bestNameToTheGUI = b'valeur_de_renvoi'
        f(bestNameToTheGUI)
     
    start(setResult)

    et vous auriez le même problème, non?

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  12. #12
    Membre actif
    J'ai testé et et effectivement, ça ne renvoie rien.

    En modifiant comme cela :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    def start(f)
        bestNameToTheGUI = b'valeur_de_renvoi'
        return f(bestNameToTheGUI)


    C'est bon.
    Mais le souci, c'est que je n'ai pas de return dans la fonction C...

  13. #13
    Membre actif
    En fait à l'origine, il y a un "connecteur" avec pyQt, c'est pourquoi (si je comprends bien), la fonction "start" n'a pas de return.

    J'ai donc modifié cette fonction "start" pour avoir un return.

    Et en toute bonne logique, ça fonctionne

    Merci wiztricks de m'avoir aiguillé vers ce qui est évident !