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 :

Appel de fonctions externes Code::blocks


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Par défaut Appel de fonctions externes Code::blocks
    Bonjour à tous,
    J'ai par le passé programmé en C avec Visual Studio.
    Aujourd'hui j'utilise l'EDI Code::blocks 13.12 sous Ubuntu 14.04

    Je souhaite regrouper mes variables globales dans un header intitulé 'globals.h'.
    Un fichier 'globals.c' est prévu, entre autre pour une fonction d'initialisation de ces variables.
    Le fichier contenant, global.h, main.cpp, globals.c appartiennent tous au projet.
    Voici globals.h
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #ifndef GLOBALS_H_INCLUDED
    #define GLOBALS_H_INCLUDED
    #include "bird.h"
     
    struct Bird Oiseau;
    int Resolx,Resoly;
    void InitGlobals();
     
    #endif // GLOBALS_H_INCLUDED

    Voici le fichier globals.c
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #include "globals.h"
    void InitGlobals()
    {
        Resolx=640;
        Resoly=480;
    };

    Enfin voici le début du fichier principal

    Code C : 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
     
    #ifdef __cplusplus
    #include <cstdlib>
    #else
    #include <stdlib.h>
    #endif
     
    #include <SDL/SDL.h>
    #include "globals.h"
     
    int main ( int argc, char** argv )
    {
        InitGlobals();
        // initialize SDL video
        if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
        {
            printf( "Unable to init SDL: %s\n", SDL_GetError() );
            return 1;
        }

    Lors de la compilation un module objet globals.0 est créé correspondant à la compilation du fichier globals.c

    Mais lorsqu'on active la commande 'build' ou 'rebuild' on a l'erreur suivante:
    ||=== Build: Debug in Flappy (compiler: GNU GCC Compiler) ===|
    /home/gilles/Documents/projets-C/Flappy/main.cpp|14|référence indéfinie vers « InitGlobals() »|
    ||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

    Qui semble indiquer un problème de linkage main ne trouve pas la définition de InitGlobals(). Je ne sais comment sortir de là.
    Si quelqu'un peut m'indiquer la nature du problème, il me semble que les fonctions C sont extern par défaut. Le prototype est bien dans le header inclus pour vérifier que l'appel est correct. C'est bien la définition de InitGlobals qui n'est pas trouvée. c'est le boulot du linker.
    Je ne comprends pas...
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  2. #2
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Par défaut Infos supplémentaires
    Ayant cherché tout l'après-midi j'ai retrouvé ce même problème de nombreuses fois sur d'autres forums. Jamais pu lire la solution...
    D'autres personnes signalent qu'en mettant un #include d'un .c cela fonctionne. c'est vrai, je l'avais remarqué mais c'est contraire aux principes de la modularité du C.
    En outre quand je reprends d'anciens projets Code::blocks multi-fichiers ils ne se compilent plus avec le même problème (impossibilité de trouver les def des fonctions externes dans les modules objets).
    Je pense de plus en plus que c'est un bug énorme de la version 13.12.
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  3. #3
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 309
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 309
    Billets dans le blog
    5
    Par défaut
    Peut-être qu'effectivement Code::blocks ne recherche pas les entêtes dans le répertoire courant. Essayes lorsque tu fais #include de spécifier le chemin complet du fichier pour voir si ca améliore un peu les choses...

  4. #4
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Par défaut
    Merci Gerald,
    Mais mon problème n'est pas un problème d'inclusion. Ce n'est pas un problème de compilation (en cas de header introuvable les messages sont distincts et la compilation est impossible). Or les modules objets sont construits, c'est une erreur de linkage, le linker n'arrive pas à fabriquer l'exécutable peut-être pour un problème de chemins.
    En fait mes fichiers objets sont dans /obj/Debug et j'ai l'impression que la recherche est faite dans /obj/Debug/obj/Debug qui n'existe pas. J'ai essayé de trouver des solutions dans le cadre de l'interface CB pour joindre au projet les modules objets soit par adressage direct, soit par adressage absolu. Sans succès !
    Voici l'erreur obtenue quand j'ajoute au projet explicitement :les fichiers objets (puisqu'il ne les trouve pas ...)
    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
     
     
    -------------- Clean: Debug in Flappy (compiler: GNU GCC Compiler)---------------
     
    Cleaned "Flappy - Debug"
     
    -------------- Build: Debug in Flappy (compiler: GNU GCC Compiler)---------------
     
    gcc -Wall -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT -g  -c /home/gilles/Documents/projets-C/Flappy/globals.c -o obj/Debug/globals.o
    g++ -Wall -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT -g  -c /home/gilles/Documents/projets-C/Flappy/main.cpp -o obj/Debug/main.o
    g++ -Lobj/Debug -o bin/Debug/Flappy obj/Debug/globals.o obj/Debug/main.o obj/Debug/obj/Debug/globals.o obj/Debug/obj/Debug/main.o  -L/usr/lib/x86_64-linux-gnu -lSDL  
    g++: error: obj/Debug/obj/Debug/globals.o: Aucun fichier ou dossier de ce type
    g++: error: obj/Debug/obj/Debug/main.o: Aucun fichier ou dossier de ce type
    Process terminated with status 1 (0 minute(s), 0 second(s))
    0 error(s), 0 warning(s) (0 minute(s), 0 second(s))
    Nous avons donc deux erreurs, mais le résumé du 'build' est optimiste puisqu'il ne les mentionne pas. Par ailleurs quand j'essaie de lancer une exécution après ce 'build' soit-disant réussi, CB prétend que le projet n'est pas construit et propose ad infinitum de rebâtir l'ensemble.
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  5. #5
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Par défaut Code::blocks déblocks !
    Finalement le même code avec un projet Geany, se compile, se construit et s'exécute parfaitement ...
    Il y a donc un problème avec la version 13.12 au moins avec les projets SDL ....mais peut-être aussi avec d'autres, mes anciens projets CB ne se compilent plus alors que l'utilisation directe de gcc ou g++ en ligne de commande marche.
    Dommage, j'avais un bon souvenir de CB.
    Je considère mon problème comme résolu (par abandon).
    Si quelqu'un sait pourquoi CB débloque, je suis preneur.
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  6. #6
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 122
    Billets dans le blog
    148
    Par défaut
    Bonjour,

    Vous avez essayé avec un "rebuild" ?
    Vous avez tenter en recréant le projet ?
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  7. #7
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Zavonen Voir le message
    Bonjour à tous,
    J'ai par le passé programmé en C avec Visual Studio.
    Aujourd'hui j'utilise l'EDI Code::blocks 13.12 sous Ubuntu 14.04

    Je souhaite regrouper mes variables globales dans un header intitulé 'globals.h'.
    Un fichier 'globals.c' est prévu, entre autre pour une fonction d'initialisation de ces variables.
    Le fichier contenant, global.h, main.cpp, globals.c appartiennent tous au projet.
    Voici globals.h
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #ifndef GLOBALS_H_INCLUDED
    #define GLOBALS_H_INCLUDED
    #include "bird.h"
     
    struct Bird Oiseau;
    int Resolx,Resoly;
    void InitGlobals();
     
    #endif // GLOBALS_H_INCLUDED

    Voici le fichier globals.c
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #include "globals.h"
    void InitGlobals()
    {
        Resolx=640;
        Resoly=480;
    };

    Enfin voici le début du fichier principal

    Code C : 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
     
    #ifdef __cplusplus
    #include <cstdlib>
    #else
    #include <stdlib.h>
    #endif
     
    #include <SDL/SDL.h>
    #include "globals.h"
     
    int main ( int argc, char** argv )
    {
        InitGlobals();
        // initialize SDL video
        if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
        {
            printf( "Unable to init SDL: %s\n", SDL_GetError() );
            return 1;
        }

    Lors de la compilation un module objet globals.0 est créé correspondant à la compilation du fichier globals.c

    Mais lorsqu'on active la commande 'build' ou 'rebuild' on a l'erreur suivante:
    ||=== Build: Debug in Flappy (compiler: GNU GCC Compiler) ===|
    /home/gilles/Documents/projets-C/Flappy/main.cpp|14|référence indéfinie vers « InitGlobals() »|
    ||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

    Qui semble indiquer un problème de linkage main ne trouve pas la définition de InitGlobals(). Je ne sais comment sortir de là.
    Si quelqu'un peut m'indiquer la nature du problème, il me semble que les fonctions C sont extern par défaut. Le prototype est bien dans le header inclus pour vérifier que l'appel est correct. C'est bien la définition de InitGlobals qui n'est pas trouvée. c'est le boulot du linker.
    Je ne comprends pas...

    Si cette discussion n'a pas encore été résolue, je dirais que le problème vient des inclusions.

    Remarque : Le fichier global.c ne sera pas inclus dans le fichier principal car tu ne l'as pas inclus dans le fichier global.h. De même tu ne l'as pas inclus dans le fichier principal, or tu as inclus dans le fichier principal le fichier global.h qui affirme l'existence d'une fonction nommée InitGlobals().
    Sauf que tu as déclaré la fonction InitGloabl() dans le fichier global.c, c'est-à-dire que tout son code est dans le fichier global.c. Ceci explique le message du compilateur au sujet de InitGlobals.

    Pour mieux comprendre, dis-toi ou rappelle-toi qu'un #include <mon_fichier> équivaut à copier tout le contenu de mon_fichier dans le fichier dans lequel tu as écrit la macro (#include) et à ce même emplacement. Si tu appliques cette vision des choses, tu verras que le fichier globals.c et donc tout son contenu n'est pas inclus dans le fichier principal et donc tout son contenu sera absent.

    Conseille (proposition 1 ou 2):

    1- Enlève le #include "globals.h" dans le fichier globals.c et écris #include "globals.c" dans le fichier globals.h (à la fin du fichier) et recompile le tout.

    2- Remplace le #include "globals.h" dans le fichier principal par un #include "globals.c", ça devrait marcher.

    Remarque:

    J'ai bâtit cette réponse à partir de mon expérience avec l'IDE TIGCC.
    Dernière modification par Invité ; 09/07/2014 à 13h19.

  8. #8
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 766
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 766
    Par défaut
    Citation Envoyé par Ratator Voir le message
    Si cette discution n'a pas encore était résolu, je dirais que le problème viens des inclusions.
    Non cela dépend si le compilateur voit cela comme une déclaration ou une définition et aussi de la politique "extern" par défaut du compilateur des variables.

    Et aussi , faire une initialisation paresseuse des variables globales assez douteuse et exposer à la fois les fonctions et les variables globales (avec des conventions de codage mauvaises)

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

Discussions similaires

  1. Réponses: 9
    Dernier message: 08/07/2009, 17h10
  2. Comment appeler une fonction externe avec XPath
    Par ttttnht dans le forum XSL/XSLT/XPATH
    Réponses: 1
    Dernier message: 19/06/2009, 13h54
  3. [Boost.Function] Appeler une fonction "externe"
    Par poukill dans le forum Boost
    Réponses: 17
    Dernier message: 29/08/2007, 16h04
  4. Réponses: 12
    Dernier message: 12/05/2006, 09h21
  5. [PHP][Javascript] PB avec appel de fonctions externes, HELP!
    Par chaser_T dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 11/04/2006, 16h44

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