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 :

exporter une fonction


Sujet :

C++

  1. #1
    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 exporter une fonction
    Bonjour, je désire exporter plusieurs fonctions pour m'en faire une librairie. Quelle est la syntaxe qu'il faut utiliser ?

    Avant, j'utilisais ceci :

    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
     
    /* Toto_API : Pour dllimport/export */
    #ifdef WIN32
    #ifdef Toto_EXPORTS
    #define Toto_API __declspec(dllexport)
    #else
    #define Toto_API __declspec(dllimport)
    #endif
    #else
    #define Toto_API
    #endif
     
    extern Toto_API void __stdcall mafct(double)
    {
     /* blabla */
    }
    mais je m'aperçois que la syntaxe suivante marche tout aussi bien

    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
     
    /* Toto_API : Pour dllimport/export */
    #ifdef WIN32
    #ifdef Toto_EXPORTS
    #define Toto_API __declspec(dllexport)
    #else
    #define Toto_API __declspec(dllimport)
    #endif
    #else
    #define Toto_API
    #endif
     
    Toto_API void mafct(double)
    {
     /* blabla */
    }
    Savez-vous pourquoi ?

    Merci d'avance

  2. #2
    Membre confirmé Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Points : 633
    Points
    633
    Par défaut
    Hum, extern, c'est pour dire que le symbole que tu utilise existe déjà et que tu laisse le linker se chargé du problème... Totalement inutile sur une déclaration...
    The mark of the immature man is that he wants to die nobly for a cause, while the mark of the mature man is that he wants to live humbly for one.
    --Wilhelm Stekel

  3. #3
    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
    Citation Envoyé par Lavock Voir le message
    Hum, extern, c'est pour dire que le symbole que tu utilise existe déjà et que tu laisse le linker se chargé du problème... Totalement inutile sur une déclaration...
    Salut, merci pour ta précision sur le mot-clé extern. Mais lorsque j'importe une fonction de ma dll, je devrais donc utiliser ce mot-clé. Hors je ne le fais pas, et ma fonction est tout de même importée. Pourquoi ? Tout est dans le dllimport ?

  4. #4
    Membre confirmé Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Points : 633
    Points
    633
    Par défaut
    Je ne connais pas trop MS oO !
    En gros, soit tu inclus le .h, donc dans se cas tes déclaration sont faite, soit tu les déclares en temps que extern, et le link s'occupe de tout.
    The mark of the immature man is that he wants to die nobly for a cause, while the mark of the mature man is that he wants to live humbly for one.
    --Wilhelm Stekel

  5. #5
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Tout tient dans les quelque lignes préprocesseur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #ifdef Toto_EXPORTS
    #define Toto_API __declspec(dllexport)
    #else
    #define Toto_API __declspec(dllimport)
    #endif
    En effet, elles ont pour résultat, lorsque tu compile ta dll, de signaler au compilateur (et au delà à l'éditeur de lien, il me semble) que les fonctions préfixées par Toto_API devront être exportées et, lorsque tu l'utilise, de ... provoquer leur déclaration auprès de l'application qui la manipule au moment du loadlibrary().

    Si tu n'utilise pas loadlibrary, l'application va se tourner, par exemple, vers le fichier def qui fournit une liste des fonctions exportées.

    Par contre, il faut être attentif à une chose:

    Les seules fonctions dont on puisse être tout à fait sur qu'elle seront utilisable quel que soit le compilateur utilisé pour créer l'application qui utilise une dll sont les fonction C, pour d'obscures raisons de convention de nommage...

    Si tu compile en C++, il faut donc veiller à ce que les fonctions exportées le soient en utilisant les noms C, et, pour ce faire, il faut veiller à les déclarer (et à les définir) dans un bloc extern "C"
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    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
    Citation Envoyé par koala01 Voir le message
    Si tu compile en C++, il faut donc veiller à ce que les fonctions exportées le soient en utilisant les noms C, et, pour ce faire, il faut veiller à les déclarer (et à les définir) dans un bloc extern "C"
    OK donc cela veut dire que je dois faire ceci ?

    fichier toto.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    extern "C" {
    Toto_API void f1(double);
    Toto_API void f2(double,double);
    } /* fin extern "C" */
    fichier toto.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    extern "C" {
    Toto_API void f1(double)
    {
      blabla
    }
     
    Toto_API void f2(double,double)
    {
      blabla
    }
     
    } /* fin extern "C" */
    ai-je bien compris ?

    Donc autant modifie ma macro Toto_API comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    /* Toto_API : Pour dllimport/export */
    #ifdef WIN32
    # ifdef Toto_EXPORTS
    # define Toto_API extern "C" __declspec(dllexport)
    # else
    # define Toto_API extern "C" __declspec(dllimport)
    # endif
    #else
    #define Toto_API extern "C" 
    #endif
    est-ce une bonne idée ?

    Merci encore

  7. #7
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par salseropom Voir le message
    OK donc cela veut dire que je dois faire ceci ?

    fichier toto.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    extern "C" {
    Toto_API void f1(double);
    Toto_API void f2(double,double);
    } /* fin extern "C" */
    fichier toto.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    extern "C" {
    Toto_API void f1(double)
    {
      blabla
    }
     
    Toto_API void f2(double,double)
    {
      blabla
    }
     
    } /* fin extern "C" */
    ai-je bien compris ?
    Cela me semble préférable, oui, mais quelqu'un pourra surement confirmer que je ne dis pas de bêtise sur ce point (jolyloic, par exemple )...

    Je sais que le problème se posera, de toutes manières, avec les fonction membres de classes, par exemple
    Donc autant modifie ma macro Toto_API comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    /* Toto_API : Pour dllimport/export */
    #ifdef WIN32
    # ifdef Toto_EXPORTS
    # define Toto_API extern "C" __declspec(dllexport)
    # else
    # define Toto_API extern "C" __declspec(dllimport)
    # endif
    #else
    #define Toto_API extern "C" 
    #endif
    est-ce une bonne idée ?

    Merci encore
    Ca, je suis moins pour, même si je ne peux trouver de justification satisfaisante...
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  8. #8
    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
    Citation Envoyé par koala01 Voir le message
    Je sais que le problème se posera, de toutes manières, avec les fonction membres de classes, par exemple
    Pour les classes, je fais "juste"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    class Toto_API MaClasse
    {
      blabla
    };
    avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    /* Toto_API : Pour dllimport/export */
    #ifdef WIN32
    # ifdef Toto_EXPORTS
    # define Toto_API extern "C" __declspec(dllexport)
    # else
    # define Toto_API extern "C" __declspec(dllimport)
    # endif
    #else
    #define Toto_API extern "C" 
    #endif

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    exporter une classe ?
    C'est tous sauf du C.

  10. #10
    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
    Citation Envoyé par bacelar Voir le message
    exporter une classe ?
    C'est tous sauf du C.
    oups, erreur de copier - coller :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    /* Toto_API : Pour dllimport/export */
    #ifdef WIN32
    # ifdef Toto_EXPORTS
    # define Toto_API __declspec(dllexport)
    # else
    # define Toto_API __declspec(dllimport)
    # endif
    #else
    #define Toto_API 
    #endif

Discussions similaires

  1. exporter une fonction
    Par Alucard95 dans le forum Général Java
    Réponses: 17
    Dernier message: 15/12/2008, 15h32
  2. exporter une fonction inline
    Par joaopa dans le forum C++
    Réponses: 3
    Dernier message: 13/10/2007, 15h09
  3. DLL:exporter une fonction qui retourne un pointeur
    Par ephemeride dans le forum C++
    Réponses: 2
    Dernier message: 29/09/2006, 11h42
  4. Récupérer le prototype d'une fonction exportée
    Par JulienDuSud dans le forum C++
    Réponses: 10
    Dernier message: 07/05/2006, 22h12
  5. Réponses: 10
    Dernier message: 02/11/2005, 11h12

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