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

MATLAB Discussion :

Compilation croisée de code C et Fortran pour création d'une dll sous RTW


Sujet :

MATLAB

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 6
    Points : 4
    Points
    4
    Par défaut Compilation croisée de code C et Fortran pour création d'une dll sous RTW
    Bonjour à tous,

    Je suis confronté à un problème de compilation ou link sous Matlab.

    Tout d'abord, pour introduire un peu mon soucis, voici quelques explications :
    • j'ai un fichier fortran 'algo.f' dans lequel j'ai une subroutine TOTO. Cette subroutine fait appel à différentes fonctions que l'on retrouve dans ce même fichier.

    • l'objectif est d'intégrer ce code fortran dans un modèle Simulink, pour au final générer une S-Fonction de ce modèle via RTW de Matlab


    Après quelques tâtonnements, j'ai compris que pour générer une S-Fonction sous RTW, il faut lui donner du code C : RTW n'accepte pas directement du Fortran, il faut donc créer un fichier C 'interface.c' dans lequel il faut définir les fonctions "d'interfaçage" entre Simulink et Fortran (avec par exemple la fonction mdlOutput...). On parle aussi de S-Fonction "inline".

    Je dispose maintenant de 2 fichiers : 'algo.f' et 'interface.c' ; il ne reste plus qu'à les compiler et les linker pour obtenir ma dll que j'intégrerai ensuite dans mon modèle Simulink.
    Cette complation s'effectue en 2 étapes :
    • création du fichier 'algo.obj' à partir du fichier Fortran. J'utilise la commande mex avec le compilateur fortran Intel Visual studio Fortran 10.1.

    • création de la dll à partir du fichier C et du fichier 'algo.obj'. J'utilise également la commande mex avec le compilateur C de base sous Matlab : lcc.


    Pour faciliter la compilation, je commence avec une subroutine fortran vide ou avec un algo très simple du style sorties=entrees. De cette manière, tout est ok : création des objets, link de ces objets et création de la dll, puis enfin génération de la S-Fonction finale sous RTW incluant cette dll et le reste du modèle.

    Après ce succès, je décide de mettre les algo voulus dans mon code Fortran : la compilation du code fortran se déroule bien, l'objet 'algo.obj' est créé sans soucis.
    Le problème intervient lors de la seconde compilation, et à mon avis lors du link... Puisque j'ai comme infos des messages du type "algo.obj .text: undefined reference to '_expf'", ce qui me laisse penser qu'il manque une ou plusieurs librairies à passer au linker. Ce besoin de ces librairies étant directement aux fonctions appelées dans mon algo Fortran.
    Dès lors, je rajoute diverses librairies mais derrière c'est l'effet cascade : pour une "undefined refrence" de résolue j'en récupère 10...

    Bref tout ça pour en arriver à ma question : comment configurer mon linker, ou comment utiliser la fonction mex pour compiler correctement et surtout linker mes objets ensemble ?

    Ci-dessous un aperçu de ce que Matlab me renvoie lors de ces compilations, avec l'option -v de la commande mex pour voir les options de compilation et de link :
    • Ici la première compilation
      >> mex -v -f mexopts_fortran.bat -c algo.f
      This is mex, Copyright 1984-2007 The MathWorks, Inc.

      -> Options file specified on command line
      ----------------------------------------------------------------
      -> Options file = mexopts_fortran.bat
      MATLAB = C:\PROGRA~1\MATLAB\R2008a
      -> COMPILER = ifort
      -> Compiler flags:
      COMPFLAGS = /fpp /Qprec "/IC:\PROGRA~1\MATLAB\R2008a/extern/include" -c -nologo -DMATLAB_MEX_FILE /fixed
      OPTIMFLAGS = /MD -Ox -DNDEBUG
      DEBUGFLAGS = /MD -Zi /PDB:"algo.mexw32.pdb"
      arguments =
      Name switch = /Fo
      -> Pre-linking commands =
      -> LINKER = link
      -> Link directives:
      LINKFLAGS = /DLL /EXPORT:MEXFUNCTION /MAP /LIBPATH:"C:\PROGRA~1\MATLAB\R2008a\extern\lib\win32\microsoft" libmx.lib libmex.lib libmat.lib /implib:C:\DOCUME~1\wt0t1123\LOCALS~1\Temp\mex_uZE9e1\templib.lib /NOLOGO
      LINKDEBUGFLAGS = /debug /PDB:"algo.mexw32.pdb"
      LINKFLAGSPOST =
      Name directive = "/out:algo.mexw32"
      File link directive =
      Lib. link directive =
      Rsp file indicator = @
      -> Resource Compiler = rc /fo "mexversion.res"
      -> Resource Linker =
      ----------------------------------------------------------------


      --> ifort /fpp /Qprec "/IC:\PROGRA~1\MATLAB\R2008a/extern/include" -c -nologo -DMATLAB_MEX_FILE /fixed /Foalgo.obj /MD -Ox -DNDEBUG -DMX_COMPAT_32 "X:\algo.f"

      >>

    • Ici la seconde compilation
      >> mex -v -f mexopts_lcc.bat interface.c algo.obj
      This is mex, Copyright 1984-2007 The MathWorks, Inc.

      -> Options file specified on command line
      ----------------------------------------------------------------
      -> Options file = mexopts_lcc.bat
      MATLAB = C:\PROGRA~1\MATLAB\R2008a
      -> COMPILER = lcc
      -> Compiler flags:
      COMPFLAGS = -c -Zp8 -I"C:\PROGRA~1\MATLAB\R2008a\sys\lcc\include" -DMATLAB_MEX_FILE -noregistrylookup
      OPTIMFLAGS = -DNDEBUG
      DEBUGFLAGS = -g4
      arguments =
      Name switch = -Fo
      -> Pre-linking commands =
      -> LINKER = lcclnk
      -> Link directives:
      LINKFLAGS = -tmpdir "." -dll "C:\PROGRA~1\MATLAB\R2008a\extern\lib\win32\lcc\mexFunction.def" -L"C:\PROGRA~1\MATLAB\R2008a\sys\lcc\lib" -libpath "C:\PROGRA~1\MATLAB\R2008a\extern\lib\win32\lcc" C:\DOCUME~1\wt0t1123\LOCALS~1\Temp\mex_pL7KD9\templib2.obj
      LINKDEBUGFLAGS =
      LINKFLAGSPOST = libmx.lib libmex.lib libmat.lib
      Name directive = -o "interface.mexw32"
      File link directive =
      Lib. link directive =
      Rsp file indicator = @
      -> Resource Compiler = lrc -I"C:\PROGRA~1\MATLAB\R2008a\sys\lcc\include" -noregistrylookup -fo"mexversion.res"
      -> Resource Linker =
      ----------------------------------------------------------------


      --> lcc -c -Zp8 -I"C:\PROGRA~1\MATLAB\R2008a\sys\lcc\include" -DMATLAB_MEX_FILE -noregistrylookup -FoC:\DOCUME~1\wt0t1123\LOCALS~1\Temp\mex_pL7KD9\interface.obj -IC:\PROGRA~1\MATLAB\R2008a\extern\include -IC:\PROGRA~1\MATLAB\R2008a\simulink\include -DNDEBUG -DMX_COMPAT_32 "X:\interface.c"


      --> lcc -c -Zp8 -I"C:\PROGRA~1\MATLAB\R2008a\sys\lcc\include" -DMATLAB_MEX_FILE -noregistrylookup "C:\PROGRA~1\MATLAB\R2008a\sys\lcc\mex\lccstub.c" -FoC:\DOCUME~1\wt0t1123\LOCALS~1\Temp\mex_pL7KD9\templib2.obj

      Contents of C:\DOCUME~1\wt0t1123\LOCALS~1\Temp\mex_pL7KD9\mex_tmp.rsp:
      C:\DOCUME~1\wt0t1123\LOCALS~1\Temp\mex_pL7KD9\interface.obj algo.obj


      --> lcclnk -o "interface.mexw32" -tmpdir "." -dll "C:\PROGRA~1\MATLAB\R2008a\extern\lib\win32\lcc\mexFunction.def" -L"C:\PROGRA~1\MATLAB\R2008a\sys\lcc\lib" -libpath "C:\PROGRA~1\MATLAB\R2008a\extern\lib\win32\lcc" C:\DOCUME~1\wt0t1123\LOCALS~1\Temp\mex_pL7KD9\templib2.obj -s @C:\DOCUME~1\wt0t1123\LOCALS~1\Temp\mex_pL7KD9\mex_tmp.rsp libmx.lib libmex.lib libmat.lib

      Writing library for interface.mexw32
      algo.obj .text: undefined reference to '_expf'
      algo.obj .text: undefined reference to '___powr4i4'
      algo.obj .text: undefined reference to '_powf'
      algo.obj .text: undefined reference to '_tanf'
      algo.obj .text: undefined reference to '_for_stop_core'
      algo.obj .text: undefined reference to '_for_cpystr'
      algo.obj .text: undefined reference to '_for_close'
      algo.obj .text: undefined reference to '_logf'

      C:\PROGRA~1\MATLAB\R2008A\BIN\MEX.PL: Error: Link of 'interface.mexw32' failed.

      ??? Error using ==> mex at 207
      Unable to complete successfully.

      >>


    Pour info j'ai rajouter la librairie libm.lib qui se trouve dans un répertoire du compilateur Fortran, en utilisant les options -L et -l de la commande mex, et c'est ainsi qu'apparaissent par la suite d'autre "undefined reference"...

    Voilà désolé pour la tartine mais je voulais donner le plus d'infos possible.
    En espérant que quelqu'un aura une idée pour résoudre mon problème, que ce soit une erreur de configuration du linker, ou même une mauvaise façon de compiler...

    Pour toute autre question n'hésitez pas...

    Dans l'attente de votre aide,
    Merci d'avance !
    Philippe

  2. #2
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 302
    Points : 52 882
    Points
    52 882
    Par défaut
    Alors... je n'ai jamais mixé des fichiers C et Fortran... et je n'utilise ni Simulnk ni RTW

    Je suppose que tu as déjà lu ceci : Creating Fortran S-Functions

    Si oui, as-tu essayé de compiler les exemples fournis dans la documentation ?

    Je vois aussi que tu utilises le compilateur LCC, as-tu essayé avec un autre ?
    => Quels sont les différents compilateurs supportés ?
    Ingénieur indépendant en mécatronique - Conseil, conception et formation
    • Conception mécanique (Autodesk Fusion 360)
    • Impression 3D (Ultimaker)
    • Développement informatique (Python, MATLAB, C)
    • Programmation de microcontrôleur (Microchip PIC, ESP32, Raspberry Pi, Arduino…)

    « J'étais le meilleur ami que le vieux Jim avait au monde. Il fallait choisir. J'ai réfléchi un moment, puis je me suis dit : "Tant pis ! J'irai en enfer" » (Saint Huck)

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 6
    Points : 4
    Points
    4
    Par défaut
    Bonjour,

    Et merci pour ta réponse.

    Effectivement j'ai déjà consulté la doc "Creating Level-2 Fortran S-Function", ce qui m'a permis de comprendre le principe pour intégrer du code Fortran, avec en particulier le besoin de "wrapper" le code Fortran avec une interface codée en C.

    Je ne peux pas utiliser d'autre compilateur que LCC puisque je n'ai que celui-là d'installé sur ma machine, mais à priori je n'ai rien vu dans la doc ou sur le net une info montrant l'incompatibilité de LCC pour mon besoin.

    Je viens de voir que la librairie math Fortran est libf2c, librairie que je n'ai pas (celle qui est avec mon compilo Fortran est libm), je vais donc tenter de la récupérer pour faire la compilation avec, sans trop me faire d'illusion...

    Dans la foulée j'essaierai un des exemple de la doc, mais de toute façon je ne pense pas que cela vienne du compilo mais bien du link, puisque je réussi à générer le tout avec une subroutine Fortran vide. Les problèmes apparaissent en codant un algo faisant référence à des fonctions externes et donc à des librairies Fortran...

    Le tout est de savoir comment faire un bon link...

    Si quelqu'un a des infos à ce sujet...
    Merci

    Philippe

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    Salut, je passe ma vie à faire communiquer du C, fortran et Matlab. Je travaille avec Visual Studio 2005. Dans la pratique j'ai ceci :

    Matlab appelle du C qui appelle du fortran qui appelle du C qui appelle du fortran qui appelle du C. Tout simplement car j'ai des morceaux de mon code en C, d'autres en fortran et que mes utilisateurs utilisent Matlab.

    Voici comment je fais :
    Tu génères avec Visual Studio autant de .dll qu'il te faut
    Tu fais un joli mex-file que tu compiles avec Visual Studio (et non pas avec Matlab chose que je n'ai jamais faite)
    Et c'est gagné !

    Je répète : tout est compilé par Visual Studio. Je n'utilise jamais la commande mex...

    J'espère que j'ai répondu à ta question

Discussions similaires

  1. Aide pour création d'une DLL
    Par BobaL dans le forum C++
    Réponses: 3
    Dernier message: 24/09/2013, 10h19
  2. Réponses: 11
    Dernier message: 05/08/2011, 11h41
  3. Réponses: 19
    Dernier message: 10/05/2006, 09h40
  4. [cmde shell pour installation d'une base sous windows]
    Par Lady_jade dans le forum Installation
    Réponses: 2
    Dernier message: 24/10/2005, 10h29
  5. Conventions à utiliser pour la création d'une DLL
    Par Writer dans le forum Langage
    Réponses: 3
    Dernier message: 02/08/2005, 09h24

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