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 :

créer une lib


Sujet :

C++

  1. #1
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Par défaut créer une lib
    Bonjour, j'aimerais créer une librairie (.a) à partir des fichiers suivants (je vous donne que les fichiers.h mais ne les lisez pas encore...):

    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    #ifndef FUNCTION_H_INCLUDED
    #define FUNCTION_H_INCLUDED
     
    #include <vector>
    #include <string>
     
    struct Variables;
    struct fc_functions;
    struct couple;
     
    namespace mp
    {
        class function
        {
            private :
                std::string fc;
                std::string simplified_fc;
                std::string result;
                std::vector<fc_function> sub_functions;
                Variables my_variables;
                bool is_simplified;
     
                void get_simplified_fc();
                void add_operators();
                void erase_spaces();
                unsigned int is_variable_or_function(std::string , unsigned int);
                bool is_sub_function(std::string, unsigned int);
                void put_parentheses_around_operator(std::string, unsigned int);
                void put_parentheses_around_functions();
                void add_parentheses();
                unsigned int pos_end(std::string chn);
                void replace();
                std::string execute(std::string);
                bool has_sub_function(std::string chn);
            public :
                void add_sub_functions(std::vector<fc_function>);
                void add_sub_functions(fc_function);
     
                function(std::string, bool=true);
                std::string calculate();
                void add_variable(couple);
                void set_value(std::string variable,double value);
        };
    }
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    #ifndef OTHER_CLASSES_H_INCLUDED
    #define OTHER_CLASSES_H_INCLUDED
     
    #include <string>
    #include<vector>
     
     
    struct couple
    {
        double num;
        std::string str;
        couple(std::string n, double val=0):str(n),num(val){};
    };
     
    struct Variables
    {
        public :
            std::vector<couple> variables;
            void add(couple v){variables.push_back(v);}
            bool put_behind_parentheses(std::string& , unsigned int );
            bool put_in_front_parentheses(std::string& , unsigned int );
            unsigned int get_v(std::string chn);
    };
     
    #endif // OTHER_CLASSES_H_INCLUDED
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    #ifndef FC_FUNCTION_H_INCLUDED
    #define FC_FUNCTION_H_INCLUDED
    #include <vector>
    #include <string>
     
    struct couple;
     
    namespace mp
    {
        struct fc_function
        {
            std::string name;
            double (*fc1)(double);
            double (*fc2)(std::vector<double>);
     
            fc_function(std::string n, double (*fc)(double), double (*fc_2)(std::vector<double>)=do_nothing);
            fc_function(std::string n, double (*fc_2)(std::vector<double>));
     
        };
        double max(std::vector<double>);
        std::string from_double(double );
        double to_double (std::string chn);
        double min(std::vector<double>);
        double my_log(std::vector<double>);
        double my_exp(std::vector<double>);
    }
     
    #endif // FC_FUNCTION_H_INCLUDED
    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
    16
    17
    18
    19
    20
    21
     
    #ifndef NEEDED_FUNCTIONS_H_INCLUDED
    #define NEEDED_FUNCTIONS_H_INCLUDED
     
    #include <vector>
    #include <string>
     
    bool is_number(char);
    double do_nothing(std::vector<double>);
    double do_nothing(double);
    unsigned int pos_end(std::string);
    void add_after_close_parentheses(unsigned int ,std::string& );
    void add_before_open_parentheses(std::string& ,unsigned int );
    bool is_number_or_parentheses(char);
    unsigned int find_operator(std::string);
    double get_number_from_operator(double ,char ,double );
    unsigned int get_occurence(std::string chn, char c);
    unsigned int get_first_number(std::string chn);
     
     
    #endif // NEEDED_FUNCTIONS_H_INCLUDED
    Je me rend bien compte que ces .h sont pas bien beaux (il manque les const...)mais j'aimerais pouvoir créer une librairie telle que les fichiers needed_functions.h et other_classes.h soient transparents
    (c'est à dire que les classes Variables et couple n'existent pas aux yeux de l'utilisateur (bien sur, il faut que functions.cpp puisse les utiliser).
    Comment faire pour générer une nouvelle librairie (c'est ma première librairie que je créée)?

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


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 126
    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 126
    Billets dans le blog
    149
    Par défaut
    Bonjour,

    J'ai lu rapidement le sujet, mais je pense que la solution est simple.
    Vous devez compiler votre lib avec vos quatres fichiers. Sur ce point pas de problèmes ( faut juste dire à Visual / ou autre que c'est une bibliothèque ).
    Pour ce qui est de la visibilité niveau utilisateur, il faut juste lui donner l'en tête avec les fonctions que vous voulez rendre visible. Et puis c'est tout. L'autre en tête n'a pas besoin d'être connu par l'utilisateur.
    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.

  3. #3
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,
    Effectivement comme le dit LittleWhite, si tu ne veux pas qu'un utilisateur ne voit les autres fonctions/classes, et bien qu'il n'inclue que le fichier d'en-tête d'export.
    Sur la production d'une bibliothèque utilisant des string/vector dans son interface, cela peut poser problème si l'utilisateur de la bibliothèque n'utilise pas le même compilateur que celui de la bibliothèque (implémentation STL différente).

  4. #4
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Par défaut
    Merci beaucoup, donc au lieu de créer un .h (qui inclue tous les autres .h) que l'utilisateur inclura, je créé un .h avec seulement les .h que l'utilisateur doit pouvoir voir.
    Mais dans ce cas se pose un nouveau problème :
    Si (le.h de) classe Machin (classe sensée être visible à l'utilisateur) à besoin de fonction truc (qui doit être invisible à l'utilisateur), comment faire ?
    Par exemple, la classe fc_function à besoin de la fonction do_nothing(pour permettre la valeur par défaut) qui se trouve dans needed_functions.
    Pour l'instant, j'ai créé un namespace extrêmement long que l'utilisateur ne pourra pas connaitre mais cette solution ne me satisfait pas.


    De plus, 3dArchi, comment gérer dans ce cas les différentes implémentation de la STL ? Faut-il créer sa propre classe vector et string ?
    Ni a t-il pas de nombreuses bibliothèques qui utilisent std::vector et std::string sans contrainte d'implémentation ? [EDIT] Pas trouvé (j'espère qu'il y a une solution pour les vector car pour les string on peut le faire en passant par des char*, peut être qu'on peut faire de même avec des itérateurs sr les vector?).

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par NoIdea Voir le message
    Merci beaucoup, donc au lieu de créer un .h (qui inclue tous les autres .h) que l'utilisateur inclura, je créé un .h avec seulement les .h que l'utilisateur doit pouvoir voir.
    Mais dans ce cas se pose un nouveau problème :
    Si (le.h de) classe Machin (classe sensée être visible à l'utilisateur) à besoin de fonction truc (qui doit être invisible à l'utilisateur), comment faire ?
    Par exemple, la classe fc_function à besoin de la fonction do_nothing(pour permettre la valeur par défaut) qui se trouve dans needed_functions.
    Pour l'instant, j'ai créé un namespace extrêmement long que l'utilisateur ne pourra pas connaitre mais cette solution ne me satisfait pas.
    pimpl idiom + déclaration anticipée.


    Citation Envoyé par NoIdea Voir le message
    De plus, 3dArchi, comment gérer dans ce cas les différentes implémentation de la STL ? Faut-il créer sa propre classe vector et string ?
    Ni a t-il pas de nombreuses bibliothèques qui utilisent std::vector et std::string sans contrainte d'implémentation ? [EDIT] Pas trouvé (j'espère qu'il y a une solution pour les vector car pour les string on peut le faire en passant par des char*, peut être qu'on peut faire de même avec des itérateurs sr les vector?).
    Avoir une interface de + haut niveau d'abstraction qui ne nécessite pas ces échanges ou alors faire une enveloppe non générique (toujours pimpl idiom) si tu n'exporte que des vecteurs de même type ou alors faire une interface à la 'C' avec des pointeurs sur les données. Voilà les premières idées qui me viennent. D'autres en auront peut être de meilleurs.

  6. #6
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Par défaut
    Le pimpl idiom me convient parfaitement.

    Sur la production d'une bibliothèque utilisant des string/vector dans son interface, cela peut poser problème si l'utilisateur de la bibliothèque n'utilise pas le même compilateur que celui de la bibliothèque (implémentation STL différente).
    Que dans l'interfaçage ? Autrement dit dans les membres public de ma classe ou tout le .h (donc les éléments privés aussi)?
    Quelles sont les différences entre les différentes implémentations STL (en pratique ça pose quoi comme contraintes) ?

    si tu n'exporte que des vecteurs de même type
    Je ne comprends pas bien. En quoi si j'ai que des std::vector<double> cela change t-il quelque chose (par rapport a des std::vector<double> et des std::vector<variables>?

    ou alors faire une interface à la 'C' avec des pointeurs sur les données.
    C'est une option tout-à fait abordable mais que je préfèrerais éviter car cette option complique l'utilisation de la bibliothèque.

    Existe-t-il d'autres options ?


    [EDIT] Il me semble que la bibliothèque GMP utilise des std::string dans son constructeur. Comment faire pareil?

    le lien : http://www.delorie.com/gnu/docs/gmp/gmp_74.html

  7. #7
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par NoIdea Voir le message
    Que dans l'interfaçage ? Autrement dit dans les membres public de ma classe ou tout le .h (donc les éléments privés aussi)?
    Oui. Tout ce qui est importé dans l'exécutable (donc le .h partagé) ne devrait pas contenir de template instancié dans la librairie et l'exécutable et échangé entre les 2.
    Citation Envoyé par NoIdea Voir le message
    Quelles sont les différences entre les différentes implémentations STL (en pratique ça pose quoi comme contraintes) ?
    Tout peut être différent. La gestion du buffer, les choix d'implémentation, et bien d'autres encore. Ca pose comme contrainte que tu donnes à ta librairie des carottes alors qu'elle pense recevoir des choux. T'es dans le potage


    Citation Envoyé par NoIdea Voir le message
    Je ne comprends pas bien. En quoi si j'ai que des std::vector<double> cela change t-il quelque chose (par rapport a des std::vector<double> et des std::vector<variables>?
    L'idée c'est de combiner pimpl idiom pour 'masquer' tes stl :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    struct mon_vecteur_double_impl;
    struct mon_vecteur_double
    {
       void push_back(double);
       double operator[](size_t ix);
    private:
    mon_vecteur_double_impl*pimpl;
    };
    // .cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    struct mon_vecteur_double_impl
    {
    std::vector<double> valeur;
    };
     
    void mon_vecteur_double::push_back(double v_)
    {
       pimpl->valeur.push_back(v_);
    }
    double mon_vecteur_double::operator[](size_t ix)
    {
       return (*pimpl)[ix];
    }
    Je reconnais que c'est assez laborieux et que ça ne peux marcher que si tu as une seule instanciation du template vector. Sinon, c'est mort.
    Citation Envoyé par NoIdea Voir le message
    C'est une option tout-à fait abordable mais que je préfèrerais éviter car cette option complique l'utilisation de la bibliothèque.
    Pour les string, c'est ce qui me choquerais le moins (l'échange d'un [w]char const * pointeur non valide au delà de son utilisation locale). Pour le reste, effectivement.

    Citation Envoyé par NoIdea Voir le message
    Existe-t-il d'autres options ?
    Pas d'autres idées entre temps

  8. #8
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Par défaut
    J'ai compris pourquoi si j'ai qu'un type de vecteur sa passait mais malheureusement j'en ai plein...([EDIT] en fait non, pourquoi ne pas créer autant de structures que de vecteurs différents que je possède ?)


    La réponse est arrivée au moment ou j'éditais l'ancien, donc je vais le remettre ici :

    Il me semble que la bibliothèque GMP utilise des std::string dans son constructeur tout en ayant un code portable. Comment faire pareil?

    Le lien : http://www.delorie.com/gnu/docs/gmp/gmp_74.html

    Si il y a vraiment aucune solution, je suis bien parti pour recoder (les parties qui m'intéressent seulement) std::vector.

  9. #9
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Par défaut
    Citation Envoyé par NoIdea Voir le message
    Il me semble que la bibliothèque GMP utilise des std::string dans son constructeur tout en ayant un code portable. Comment faire pareil?
    Sans doute parcequ'ils ne distribuent pas de .a/lib/dll/so/..., bref : pas de fichier pré-compilé.
    Tu télécharges les sources et tu compile sur ta machine : comme ça tu es sûr que la bibliothèque utilise le même environnement (implémentation de STL, etc) que le programme qui s'en sert.
    Si ta bibliothèque n'a que très peu de dépendances, c'est une option intéressante, à condition de fournir à l'utilisateur de quoi compiler facilement (MakeFile, projet Code::Block ou Visual, ...).
    Mais si tu as besoin de 20 autres libs pour pouvoir compiler (qui ont certainement elles aussi des dépendances ), ça devient vite un cauchemar pour le pauvre utilisateur... Enfin, sauf s'il travaille sous Linux avec apt-get ou équivalent (le gestionnaire Synaptic de Ubuntu est vraiment impressionnant, au passage).

  10. #10
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par NoIdea Voir le message
    Si il y a vraiment aucune solution, je suis bien parti pour recoder (les parties qui m'intéressent seulement) std::vector.
    Il ne s'agit pas de tout recoder mais d'utiliser un pimpl-idiom (aussi DP enveloppe/lettre) et de ne définir que les fonctions d'interfaces dont tu peux avoir besoin (push_back, at, [], etc...?). Pour la machinerie effective, garde les std::vector. Pas besoin de réinventer la roue.

  11. #11
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Par défaut
    si tu n'exporte que des vecteurs de même type
    3dArchi j'utilise différents types de vecteurs dans mon interface. Pourquoi ce que tu proposes ne marcherait qu'avec un type de vecteur? Si sa marche avec plusieurs, je fais sa...
    De plus si je veux juste m'assurer que ma lib marche avec gcc (les autres pourrons toujours tout recompiler), l'implémentation change-t-elle en fonction de la version ?

  12. #12
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Ca marche avec plusieurs types différents. C'est juste que ça devient un peu plus laborieux et donc un peu plus de chance d'introduire du bug .
    Dans ce cas, un enum combiné avec une type erasure sur l'implémentation (du pimpl) peut être une piste.

  13. #13
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Par défaut
    Merci beaucoup, mais la sa devient un peu trop compliquer pour moi, je vais plutôt donner un makefile et laisser les gens compiler...

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

Discussions similaires

  1. Créer une lib dynamique avec des lib statiques
    Par skeleton18 dans le forum C
    Réponses: 3
    Dernier message: 11/06/2011, 12h05
  2. [GCC] Créer une lib à partir de plusieurs lib
    Par manrugby dans le forum Autres éditeurs
    Réponses: 6
    Dernier message: 14/01/2010, 10h05
  3. Créer une .lib compatible avec MinGW
    Par erqsor dans le forum C++
    Réponses: 2
    Dernier message: 05/05/2009, 10h26
  4. Réponses: 6
    Dernier message: 02/10/2008, 00h02
  5. comment créer un rpm à partir d'une lib source
    Par kris1 dans le forum Applications et environnements graphiques
    Réponses: 1
    Dernier message: 06/12/2007, 17h35

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