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

Réseau C Discussion :

Appeler une lib C++ en C (logging en C)


Sujet :

Réseau C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 33
    Par défaut Appeler une lib C++ en C (logging en C)
    Bonjour,

    j'ai un peu de mal à trouver la réponse à ma question sur le net. Cela concerne la possibilité d'appeler une librairie C++ à partir d'un programme C.

    Pour donner un exemple concret, je souhaite utiliser la librairie de logging d'Apache Log4cxx (http://logging.apache.org/log4cxx/) qui est écrite en C++ dans mon programme écrit en C.

    Ce qui pourrait peut-être arranger les choses, c'est que les sources de la librairie de logging sont fournies. Donc, éventuellement, il serait possible d'encapsuler la librairie Log4cxx dans du code pure C.

    Je vois par exemple qu'il est possible d'appeler du code C à partir d'un code C++ (http://c.developpez.com/faq/cpp/?pag...RS_fonctions_C) mais je ne suis pas sur de comprendre précisemment l'impact si l'on déclare en extern des méthodes de la librairie Log4cxx. De plus, la librairie utilise le patter de singleton qui permet de récupérer une instance du logger qui est un objet. Sachat que l'on ne peux pas manipuler d'objets en C, peut-etre que justement une surcouche permettrait de gérer ce problème...

    Mes souvenirs de programmation C sont trop lointains et j'avoue que je ne sais pas comment formuler la question dans Google (net ou news) et Cie pour avoir une réponse pertinente à ce problème. J'avoue que je n'ai pas testé ce que j'ai dit ci-dessus car je n'ai pas mon environnement de travail ce week end, mais je souhaite cogiter sur le sujet...

    Au passage, peut-être que quelqu'un connait une librairie de logging en C? Mais j'avoue que les possibilités offertes par celle d'Apache sont bien attrayantes (écriture dans un fichier, base de données, socket, etc.)

    Merci d'avance pour vos éclairages sur le domaine

  2. #2
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par evguen
    j'ai un peu de mal à trouver la réponse à ma question sur le net. Cela concerne la possibilité d'appeler une librairie C++ à partir d'un programme C.
    Ce n'est pas toujours possible. Si certaines fonctions de la bibliotheque prennent en argument une instance de classe, ou le pointeur this, pour ne citer que ces cas là, t'es mal (bon, y'a des hacks horribles pour faire l'interface, mais faut être sportif...).
    Si les fonctions exportées ne prennent que des arguments 'classiques', c'est plus facile, mais il faut faire attention aux conventions d'appel, etc.; et utiliser des compilateurs qui se comprennent (gcc en mode C et en mode C++, par exemple).

    Mais le plus simple serait de tout faire en C++. Tu n'es pas obligé de recoder, juste de convertir ton code en C en un C++ valable, codé "à la C".

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 38
    Par défaut
    Bonjour

    Je vois par exemple qu'il est possible d'appeler du code C à partir d'un code C++ (http://c.developpez.com/faq/cpp/?pag...RS_fonctions_C) mais je ne suis pas sur de comprendre précisemment l'impact si l'on déclare en extern des méthodes de la librairie Log4cxx
    Je ne suis pas sûr d'avoir bien compris. Il me semble que le mot-clé extern (comme indiqué sur le lien que tu mentionnes) permet d'appeler une fonction C depuis un code C++ (en particulier extern signale au compilateur de ne pas décorer le nom de la fonction selon les conventions C++, la décoration est un mécanisme C++ pour permettre à plusieurs fonctions de partager le même nom). N'était-ce pas l'inverse que tu voulais faire (appel de C++ depuis C) ?

    Mais le plus simple serait de tout faire en C++. Tu n'es pas obligé de recoder, juste de convertir ton code en C en un C++ valable, codé "à la C".
    Je suis parfaitement d'accord avec Da Zumba. Les incompatibilités C/C++ sont rares et concerne des propriétés rarement utilisées du C. L'une des plus notables est relative aux fonctions déclarées sans argument qui n'ont pas la même signification en C et en C++. En C, c'est une fonction pouvant recevoir un nombre quelconque d'arguments de tout type, en C++ c'est une fonction ne pouvant prendre aucun argument. La plupart des autres incompatibilités concerne des pratiques de programmation C à éviter dans la mesure du possible (int implicite, affectation d'un enum à un int, etc).

    Si malgré tout, tu tiens à (ou dois) absolument utiliser un compilateur C, dans ce cas il faudra effectivement que tu plonges dans les arcanes de l'interfaçage C/C++. Une référence est la FAQ Lite de Marshall Cline, section How to mix C and C++

    L'une des raisons pour lesquels je voudrais personnellement appeler du C++ depuis du C strict serait de développer une bibliothèque de routines C réutilisables, interfaçant ou exploitant du code C++ existant. Peut-être est-ce ton idée ?

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 33
    Par défaut
    Citation Envoyé par DaZumba
    Ce n'est pas toujours possible. Si certaines fonctions de la bibliotheque prennent en argument une instance de classe, ou le pointeur this, pour ne citer que ces cas là, t'es mal (bon, y'a des hacks horribles pour faire l'interface, mais faut être sportif...).
    Je vois bien le problème. Dans ce cas concret du logger, voici l'emeple trivial d'utilisation du logger issu des fichiers exemple accompagnant le package:

    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
     
    #include <stdlib.h>
    #include <log4cxx/logger.h>
    #include <log4cxx/basicconfigurator.h>
    #include <log4cxx/helpers/exception.h>
    #include <log4cxx/ndc.h>
     
    using namespace log4cxx;
    using namespace log4cxx::helpers;
     
    int main()
    {
        int result = EXIT_SUCCESS;
        try
        {
    		BasicConfigurator::configure();
     		LoggerPtr rootLogger = Logger::getRootLogger();
     
    		NDC::push(_T("trivial context"));
     
    		rootLogger->debug(_T("debug message"));
    		rootLogger->info(_T("info message"));
    		rootLogger->warn(_T("warn message"));
    		rootLogger->error(_T("error message"));
    		rootLogger->fatal(_T("fatal message"));
    	}
    	catch(Exception&)
    	{
    		result = EXIT_FAILURE;
    	}
     
        return result;
    }
    On y vois :
    • l'appel à une méthode statique BasicConfigurator::configure();
    • la récupération d'une instance d'une classe LoggerPtr (mécanisme de singleton)
    • l'appel à des méthodes de la classe LoggerPtr tels que debug, info, etc.
    ,

    Je m'intéresse pour l'instant aux possibilités de traiter ce cas d'utilisation. Ainsi, je pensais à créer un fichier avec du code pure C qui, par exemple, va créer une instance globale de LoggerPtr rootLogger pour qu'elle puisse être utilisée par les méthodes debug et info que j'aurais également encapsulé.

    Citation Envoyé par DaZumba
    Mais le plus simple serait de tout faire en C++. Tu n'es pas obligé de recoder, juste de convertir ton code en C en un C++ valable, codé "à la C".
    Je dois intégrer une librairie de logging performante dans une application existante. Je n'ai donc pas beaucoup de liberté dans ce cas.

    Citation Envoyé par Corentor
    N'était-ce pas l'inverse que tu voulais faire (appel de C++ depuis C) ?
    Si-si c'est bien l'utilisation de code C++ à partir d'un programme C.

    Citation Envoyé par Corentor
    L'une des raisons pour lesquels je voudrais personnellement appeler du C++ depuis du C strict serait de développer une bibliothèque de routines C réutilisables, interfaçant ou exploitant du code C++ existant. Peut-être est-ce ton idée ?
    Je crois qu'on s'est bien compris. L'exemple concret que je traite est la possibilité d'utiliser la librairie de logging Log4cxx dans du code C.

    Merci à tous pour vos idée sur le sujet

  5. #5
    Membre émérite

    Profil pro
    Inscrit en
    Août 2003
    Messages
    878
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 878
    Par défaut
    Bonjour,

    Est-ce que la bibliothèque Log4c pourrait répondre à ton besoin ?
    Elle ne permet pas d'appeler la bibliothèque C++ de tes rêves, mais, je cite le résumé de la page d'accueil du site :
    Log4c is a library of C for flexible logging to files, syslog and other destinations. It is modeled after the Log for Java library (http://jakarta.apache.org/log4j/), staying as close to their API as is reasonable.
    Cordialement,
    DS.

    PS : une autre bibliothèque (C++) qui semble intéressante : Pantheios

  6. #6
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par evguen
    j'ai un peu de mal à trouver la réponse à ma question sur le net. Cela concerne la possibilité d'appeler une librairie C++ à partir d'un programme C.
    Pour faire simple : Pas possible.

  7. #7
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par evguen
    Sachat que l'on ne peux pas manipuler d'objets en C, peut-etre que justement une surcouche permettrait de gérer ce problème...
    En écrivant une surcouche (compilée en C++) et en écrivant le main en C++, c'est possible. Si en plus tu as des passages C++ -> C -> C++, il ne faut pas t'attendre à ce que les exceptions puissent passer à travers le C; ça dépend des platerformes. Il faut donc catcher les exceptions à l'interface et rapporter le problème à l'appelant d'une façon différente.

    Le truc, c'est que les fonctions C++ qui doivent être appelées du C doivent être déclarée extern "C". Un exemple tout simple:

    Déclaration de la classe (code C++, jamais vu du C)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class compteur {
    public:
       foo() : v_(0) {}
       foo& operator++() { v_++; }
       void reset() { v_ = 0; }
       int get() const { return v_ };
    private:
       int v_;
    }
    Fichier d'interface (inclus en C et en C++)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #ifdef __cplusplus
    extern "C" {
    #endif
    struct compteur;
     
    compteur* compteur_new();
    void compteur_delete(compteur*);
    void compteur_inc(compteur*);
    void compteur_reset(compteur*);
    int compteur_get(compteur*);
    #ifdef __cplusplus
    }
    #endif
    Implémentation de l'interface (C++, appelé directement du C)
    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
    compteur* compteur_new() {
       return new compteur();
    }
     
    void compteur_delete(compteur* c) {
       delete c;
    }
     
    void compteur_reset(compteur* c) {
       c->reset();
    }
     
    void compteur_inc(compteur* c) {
       ++ *c;
    }
     
    int compteur_get(compteur* c) {
       return c->get();
    }

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 33
    Par défaut
    Je vous remercie pour vos précieuses indications, je vais regarder tout cela de plus près et voir quelle est la meilleure alternative à mon problème et mon contexte d'utilisation.

    Y'a plus qu'à!

    Merci encore

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 11/05/2011, 09h27
  2. Choisir une lib de log
    Par pavel dans le forum C++
    Réponses: 3
    Dernier message: 02/12/2009, 23h23
  3. Pb appel fonction dans une lib
    Par mamok dans le forum MFC
    Réponses: 14
    Dernier message: 01/02/2006, 18h40
  4. Chargement d'une lib partagée C++ dans un programme C
    Par Zero dans le forum Autres éditeurs
    Réponses: 4
    Dernier message: 30/09/2003, 16h40
  5. Appeler une fonction avec/sans parenthèses
    Par haypo dans le forum Algorithmes et structures de données
    Réponses: 8
    Dernier message: 29/12/2002, 18h48

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