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 :

Utilisation d'un tableau déclaré dans une librairie.


Sujet :

C

  1. #1
    Membre éclairé
    Avatar de Elijha
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Avril 2003
    Messages
    314
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Avril 2003
    Messages : 314
    Points : 742
    Points
    742
    Par défaut Utilisation d'un tableau déclaré dans une librairie.
    Bonjour,

    Je but sur un problème de compilation avec un tableau déclaré en externe dans une librairie. Lors de l'édition des liens, il ne trouve pas la référence de ce tableau
    In function `record': undefined reference to `tabRecord'

    J'ai une librairie dans laquelle j'ai déclaré un tableau en extern. J'utilise ce tableau dans les différents modules C de cette librairie (déclartion n°1).
    Je veux pouvoir accéder à ce tableau en dehors des modules de la librairie, mais en lecture seulement (déclaration n°2).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    // record.h
    ...
    #ifndef __LIB_RECORD_H__
    extern uint8_t tabRecord[MAXRECORD] ;           // Déclaration pour les modules de la librairie
    #else
    extern const uint8_t tabRecord[MAXRECORD] ;     // Déclaration pour les utilisateurs de la librairie
    #endif
    ...
    Et en globale dans le module C
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    // record.c
    #include "record.h"
    ...
    uint8_t tabRecord[MAXRECORD] ;
    ...
    Lors de la compilation et l'archivage de la librairie, un fichier d'entête est créé où l'on retrouve seulement la deuxième déclaration. J'obtiens donc en final un fichier librecord.a et librecord.h
    Nota: MAXRECORD est défini dans une entête commune à toutes les librairies et programmes.


    J'ai une seconde librairie qui doit pouvoir avoir accéder au tableau de la première librairie en lecture seulement. Donc dans le module C, j'ai déclaré en entête le fichier H.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #include "librecord.h"    // Extern const de tabRecord
    ...
    int record(void) {
    ...
        if(!tabRecord[x]) ...   // Utilisation du tableau en lecture seulement
    ...
    }
    Lors de la compilation des dépendances (autres lib) et de la compilation et l'archivage de cette seconde librairie, pas de problème (0 erreur et 0 warning).


    Lors de la compilation globale du programme final, tous ce déroule bien jusqu'à l'édition des liens où cela me sort l'erreur décrite ci-dessus.
    - C'est le seul tableau utilisé par une autre librairie (même pas par le main).
    - Je n'ai aucun problème pour d'autres variables externes (complexe ou pas) ou pour les fonctions inter-librairies.
    - Je n'ai pas de problème de chemin ou d'options de compilation dans le Makefile (toutes les archives sont présentes lors du linkage).


    Je ne vois qu'un problème de déclaration dans mes fichiers, mais lequel ?

    Merci pour votre aide.


    Compilateur: gcc (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 136
    Points
    23 136
    Par défaut
    Bonjour,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #ifndef __LIB_RECORD_H__
    extern uint8_t tabRecord[MAXRECORD] ;           // Déclaration pour les modules de la librairie
    #else
    extern const uint8_t tabRecord[MAXRECORD] ;     // Déclaration pour les utilisateurs de la librairie
    #endif
    As-tu essayé de ne mettre que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    extern uint8_t tabRecord[MAXRECORD] ;
    Pour voir si le problème ne viens pas de là?

    Il me semble que les variables constantes ne sont pas placés au même endroit dans la mémoire que les variables non-constantes, le compilateur fait peut être une distinction entre la version const et la version non const d'où l'erreur lors de l'édition des liens ?

    Sinon pourquoi ne pas utiliser une macro pour la lecture seule?

  3. #3
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 195
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 195
    Points : 17 162
    Points
    17 162
    Par défaut
    Et pourquoi ne pas avoir une fonction dédiée à l'accès en lecture?
    Quelque chose du style de uint8_t record(int numero);.

  4. #4
    Membre éclairé
    Avatar de Elijha
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Avril 2003
    Messages
    314
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Avril 2003
    Messages : 314
    Points : 742
    Points
    742
    Par défaut
    Bonjour,

    Citation Envoyé par Neckara Voir le message
    As-tu essayé de ne mettre que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    extern uint8_t tabRecord[MAXRECORD] ;
    Pour voir si le problème ne viens pas de là?
    Je viens de faire le test, et j'ai malheureursement la même erreur.

    Citation Envoyé par Neckara Voir le message
    Il me semble que les variables constantes ne sont pas placés au même endroit dans la mémoire que les variables non-constantes
    , le compilateur fait peut être une distinction entre la version const et la version non const d'où l'erreur lors de l'édition des liens ?
    Je vais vérifier cela en détail. Mais c'est vrai que cette déclaration est un peu alambiquée. Je vais oublier le const pour l'instant en attendant de trouver plus d'informations sur les placements des variables de type const en mémoire.

    Citation Envoyé par Neckara Voir le message
    Sinon pourquoi ne pas utiliser une macro pour la lecture seule?
    Par contre je ne vois pas comment utiliser une macro pour faire cela.


    Merci pour ton aide.

  5. #5
    Membre éclairé
    Avatar de Elijha
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Avril 2003
    Messages
    314
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Avril 2003
    Messages : 314
    Points : 742
    Points
    742
    Par défaut
    Bonjour,

    Citation Envoyé par leternel Voir le message
    Et pourquoi ne pas avoir une fonction dédiée à l'accès en lecture?
    Quelque chose du style de uint8_t record(int numero);.
    J'y ai pensé aussi, mais c'est un appel de plus à une fonction (et tous ce que ça engendre) alors que ces informations sont déjà en mémoire.
    Je me suis penché aussi sur l'utilisation d'un pointeur sur ce tableau, mais il faut vraiment faire attention lors de son utilisation.

    Merci.

  6. #6
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 136
    Points
    23 136
    Par défaut
    Citation Envoyé par Elijha Voir le message
    Par contre je ne vois pas comment utiliser une macro pour faire cela.
    Je dois avouer que je n'utilise pas les macro très régulièrements
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    uint8_t tmp; //attention dans un contexte multithread, penser à le mettre dans la mémoire non partagée.
     
    #define getValue(X) (tmp = tabRecord[X] )
    Et si tu tentes de faire getValue(1) = 2; il me semble que '2' sera stocké dans tmp.

    Après tu auras toujours une copie du dernier accès dans tmp (qu'on peut même renommer lastAcces), ça peut être utile dans certains cas.


    Pour l'utilisation d'un pointeur, je trouve que c'est plutôt une bonne idée.
    Après il faut bien penser à créer un pointeur constant sur une valeur constante.
    Il ne faudra pas non plus oublier de créer une constante TailleTabRecord.

  7. #7
    Membre éclairé
    Avatar de Elijha
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Avril 2003
    Messages
    314
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Avril 2003
    Messages : 314
    Points : 742
    Points
    742
    Par défaut
    Bonjour,

    La solution est de compiler les librairies et le main dans le bon ordre ! Simple, n'est-ce pas ?
    Citation Envoyé par Elijha Voir le message
    - Je n'ai pas de problème de chemin ou d'options de compilation dans le Makefile (toutes les archives sont présentes lors du linkage).
    Effectivement dans les Makefile des librairies, mais pas dans celui du programme. Pour avoir une visibilité de la variable (ici tabRecord), il faut au moment du linkage insérer la deuxième librairie puis ensuite la première.



    Avec librecord qui déclare le tabRecord et libmark qui lis seulement le tableau tabRecord.
    Citation Envoyé par Ce qu'il ne faut pas faire
    gcc main.o ../librecord/librecord.a ../libmark/libmark.a -o datalog -lm -lmxml -lsqlite3
    Citation Envoyé par Ce qu'il faut faire
    gcc main.o ../libmark/libmark.a ../librecord/librecord.a -o datalog -lm -lmxml -lsqlite3
    Je pensais qu'il fallait mettre en premier les lib qui déclaraient les variables et ensuite celles qui les "utilisaient". Donc méfiance lorsque vous faites votre Makefile; Ordonnez correctement les fichiers lors du linkage.
    On ne m'y reprendra pas


    Je vous remercie de votre aide et bonne fin de journée.

  8. #8
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 678
    Points
    13 678
    Billets dans le blog
    1
    Par défaut
    Spontanément, j'aurais fait comme toi. Je vais essayer de le retenir mais je pense que j'aurais oublié le jour où j'en aurais besoin

  9. #9
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Bktero Voir le message
    Spontanément, j'aurais fait comme toi. Je vais essayer de le retenir mais je pense que j'aurais oublié le jour où j'en aurais besoin
    C'est assez simple. Les arguments sont traités dans leur ordre d'apparition. D'une bibliothèque statique, on ne tire que les objets dont on a besoin. Si on commence par la bibliothèque, on n'a à ce moment là besoin de rien puisque les autres objets -- ceux qui font références aux objets de la bibliothèque -- n'ont pas encore été vus. C'est la même raison qui fait que parfois il faut répéter plusieurs fois une bibliothèque statique.

  10. #10
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 678
    Points
    13 678
    Billets dans le blog
    1
    Par défaut
    C'est logique en effet. Merci pour cette explication !

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

Discussions similaires

  1. Utilisation d'un tableau java dans une fonction JS
    Par bilou69 dans le forum Général JavaScript
    Réponses: 24
    Dernier message: 19/07/2011, 12h32
  2. Utiliser le fichier de configuration dans une librairie jar
    Par Palsajicoco dans le forum Hibernate
    Réponses: 0
    Dernier message: 16/05/2011, 13h32
  3. utilisation d'un tableau 3D dans une jsp
    Par rudyhadoux2 dans le forum Servlets/JSP
    Réponses: 0
    Dernier message: 15/09/2009, 16h07
  4. Réponses: 3
    Dernier message: 03/08/2008, 12h35
  5. Réponses: 5
    Dernier message: 27/08/2006, 14h24

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