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

Interfaçage autre langage Python Discussion :

Appeler une fonction d'une DLL compilée depuis Fortran [Python 3.X]


Sujet :

Interfaçage autre langage Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 662
    Par défaut Appeler une fonction d'une DLL compilée depuis Fortran
    Bonjour,

    Admettons le code Fortran suivant (add_f.f90) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function add(x, y)
     
        implicit none
     
        double precision             :: add
        double precision, intent(in) :: x, y
     
        add = x + y
     
    end function add
    Je peux le compiler en une library comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    gfortran -c -fno_underscoring add_f.90
    gfortran -shared -fPIC -o add_f.so add_f.o
    Je peux vérifier le contenu de la library :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    nm -D add_f.so
    00000000000010f9 T add
                     w __cxa_finalize
                     w __gmon_start__
                     w _ITM_deregisterTMCloneTable
                     w _ITM_registerTMCloneTable
    Je souhaite maintenant appeler la fonction add depuis un script Python. Je me suis inspiré pour cela du sujet suivant : https://www.developpez.net/forums/d2.../#post11404304

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    import ctypes
     
    # Définition de la fonction add depuis la library
    libf = ctypes.CDLL('add_f.so')
    func = libf.add
     
    # Définition du type des arguments et de la sortie
    func.argtypes = [ctypes.c_double, ctypes.c_double]
    func.restype = ctypes.c_double
     
    # test
    res = func(1.2, 3)
     
    print(res)
    Qui me renvoie un messagre d'erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    /tmp/geany_run_script_SE8FJ0.sh: line 7: 54151 Segmentation fault
    Si je ne spécifie pas le type des arguments j'ai un message d'erreur de type TypeError.

    Qu'est-ce qui est incorrect ici ?

    J

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 698
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 698
    Par défaut
    Salut,

    Quand je me lance dans des opérations inhabituelles, je cherche un peu sur Internet d'abord. Ce que je n'ai pas manqué de faire en lisant votre sujet. Ah ben ouais, on peut le faire sans trop de problèmes pourvu qu'on passe ses arguments par référence et qu'on fasse un peu attention aux variations dans les types.

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

  3. #3
    Membre émérite

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 662
    Par défaut
    Bonjour Wiztricks,

    Je ne saisi pas en quoi mon exemple diffère des exemples que j'ai pu voir sur la doc de ctypes. Il me manque une pièce au puzzle.

    Je me suis penché sur cette notion de "par référence" et "par valeur". Pour moi les arguments x et y ne doivent pas être passés par référence. Peut être la valeur de retour, add, doit l'être elle.

    Mais si je teste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    from ctypes import CDLL, POINTER, c_double
     
    libf = CDLL('add_f.so')
    func = libf.add
    func.restype = POINTER(c_double)
     
    # Test
    res = func(c_double(1.2), c_double(3))
     
    print(res)
    J'obtiens un pointer <__main__.LP_c_double object at 0x7fac006a4ae8>. Et dès que j'essaie d'accéder à sa valeur par l'attribut .contents, je me retrouve avec un segfault à nouveau.

    J

  4. #4
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 698
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 698
    Par défaut
    Salut,

    Citation Envoyé par Julien N Voir le message
    Je ne saisi pas en quoi mon exemple diffère des exemples que j'ai pu voir sur la doc de ctypes. Il me manque une pièce au puzzle.
    La documentation de ctypes vous explique juste comment charger une DLL, fabriquer les arguments des fonctions, les appeler,...

    Elle ne vous dira pas que telle fonction de la DLL devra être appelée avec des arguments par référence ou par valeur. Et comme ctypes est plutôt orienté C, çà ne racontera pas grand chose non plus sur Fortran.

    Après, si vous voulez réinventer la roue plutôt que de voir comment çà peut se faire en cherchant un peu sur Internet...

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

  5. #5
    Membre émérite

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 662
    Par défaut
    Croyez bien que si je pose une question c'est que je n'ai pas trouvé la réponse par moi-même. Il est plus facile de trouver une réponse lorsqu'on sait ce que l'on recherche. C'est pour cette raison que ma question initiale est :

    Qu'est-ce qui est incorrect ici ?
    Je ne vois pas en quoi je réinvente la roue en essayant de faire marcher un exemple simple destiné à comprendre comment cela fonctionne.

  6. #6
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 698
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 698
    Par défaut
    Citation Envoyé par Julien N Voir le message
    Je ne vois pas en quoi je réinvente la roue en essayant de faire marcher un exemple simple destiné à comprendre comment cela fonctionne.
    Tous les exemples que j'ai trouvé disent (et montrent) qu'avec fortran, les arguments sont appelés par référence...

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

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Appeler une dll C# depuis VBA
    Par doudblast dans le forum Général Dotnet
    Réponses: 4
    Dernier message: 17/08/2009, 15h07
  2. Appeler une DLL depuis Javascript
    Par troubleshooting dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 01/07/2008, 14h45
  3. Appel d'une DLL C depuis VB
    Par oliver_mpt dans le forum Windows
    Réponses: 6
    Dernier message: 13/06/2008, 14h40
  4. appeler une DLL depuis un executable
    Par xxiemeciel dans le forum Framework .NET
    Réponses: 10
    Dernier message: 09/07/2007, 14h42
  5. Appel de fonctions d'une DLL C++ depuis Java
    Par max_rossito dans le forum API standards et tierces
    Réponses: 1
    Dernier message: 11/01/2007, 22h54

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