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

Windows Discussion :

ordinal d'une fonction dans une dll


Sujet :

Windows

  1. #1
    Membre actif Avatar de peijnoob
    Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    279
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 279
    Points : 294
    Points
    294
    Par défaut ordinal d'une fonction dans une dll
    Bonjour à tous

    Je voulais savoir comment définir un ordinal (un numéro de ressource si j'ai bien compris) pour une fonction dans une dll.

    En effet, j'ai 2 types d'appels :

    Soit on importe les fonctions dans des pointeurs en les référencant par leur nom;
    Soit un se reporte à leur ordinal.

    Seulement, je ne sais pas du tout comment attribuer tel numéro à telle fonction.

    J'ai testé une syntaxe qui ne m'a pas l'air correcte :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    DLLIMPORT int __stdcall _maFonction@1        (void) ;
    Ca passe sans problème avec Dev C++ et son compilateur par défaut, il ne me sort pas d'erreur a la compilation et ça marche bien avec les programmes qui appellent la dll.

    Par contre sous code::blocks, avec gcc, j'ai des erreurs de compilation qui me disent :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    dll.h:64: error: stray '@' in program
    dll.h:64: error: syntax error before numeric constant
    A qui dois-je me fier ? Et quelles autres solutions existe-t-il pour respecter la norme ??

    Merci d'avance pour vos réponses

  2. #2
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    A qui dois-je me fier ? Et quelles autres solutions existe-t-il pour respecter la norme ??
    Je ne crois pas que l'utilisation de DLL soit définie dans la norme. Mais c'est étrange que ça fonctionne avec Dev-C++ et pas avec Code::Blocks.

    Thierry

  3. #3
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Le @ ne signifie pas Ordinal.
    le @ fait partie du nom "décoré" d'une fonction C (ou extern "C") en __stdcall ou en __fastcall.

    Le peu que je sache sur l'ordinal:
    http://msdn.microsoft.com/library/de...rocaddress.asp

    Les conventions de décoration:
    http://msdn.microsoft.com/library/de...onventions.asp
    (voir les rubriques des différents types)

  4. #4
    Membre actif Avatar de peijnoob
    Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    279
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 279
    Points : 294
    Points
    294
    Par défaut
    Merci pour vos réponses

    Alors, concernant le @, j'en ai rencontré 2 types différents jusqu'a présent :

    -Celui qui décore le nom de la fonction (comme dit par Médinoc), mais qui indique en fait la taille des paramètres de la fonction.

    -Celui qui indique le numéro de la fonction (et c'est celui là qui m'intéresse)

    Je suis pas très avancé en C (j'apprends, mais c'est pas facile ^^) et sur ce genre de choses, je m'y paume un peu.

    Le GetProcAdress marche aussi bien avec le nom de la fonction que l'on veux appeler que par un ordinal qui lui correspond.

    La déclaration dans le code d'une appli utilisant ma dll ressemble à ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define MA_FONCTION  MAKEINTRESOURCE(1)
    Puis le getProcAddress (je vous éparge la déclaration du pointeur ^^
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    MaFonction=(PFMAFONCTION)GetProcAddress((HINSTANCE)DllHandle, MA_FONCTION);
    Sauf que je ne peux pas toucher au code source du programme appelant pour changer les numéros dans les MAKEINTRESOURCE.

    Du coup, il faut que je puisse définir manuellement ces numéros (d'où les @, qui passent sous Dev C++ et pas sous Code::blocks).

    Le problème est que Code::Block utilise gcc (pour Dev C++, je sais pas c'est quoi). Il me semble bien que gcc est le compilateur le plus utilisé à l'heure actuelle. Et si quelqu'un doit maintenir ma dll plus tard, je voudrais éviter qu'il ait à tout refaire parce qu'il n'utilise pas le même compilo.

    Sinon, j'ai regardé l'aide de la MSDN, mais ça ne m'apporte pas grand chose, dommage

  5. #5
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Sous Visual, pour forcer le nom d'exportation et l'ordinal d'une fonction, on utilise un Module-Definition File (fichier .def). Il me semble qu'il existe un équivalent pour GCC, qui est même l'unique moyen de choisir les exports d'une .so de Linux...

  6. #6
    Membre actif Avatar de peijnoob
    Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    279
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 279
    Points : 294
    Points
    294
    Par défaut
    Oui, mais dans ce cas, il faut que ce fichier .def soit utilisé par l'application appelante, non ?

    Enfin, je vais pour le moment utiliser la méthode Dev-C++, il faut que je sorte un truc qui fonctionne assez rapidement (Emmanuel, pas taper stp ).

    Ce n'est pas propre, mais il faut vraiment que j'avance. Quand j'aurai un peu plus de temps après, je me pencherai plus sur le problème pour étudier leur fonctionnement.

    Merci encore pour vos réponses

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Citation Envoyé par peijnoob
    Oui, mais dans ce cas, il faut que ce fichier .def soit utilisé par l'application appelante, non ?
    Non, non. Il suffit juste que les ordinaux et/ou les noms soient connus de l'application appelante (Pour un GetProcAddress(), ils peuvent carrément être écrits en dur dans le source, l'important est que ce soient les mêmes.

    Exemple:
    Code Def : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    EXPORTS
    MaFonction @1
    MonAutreFonction @2

  8. #8
    Membre actif Avatar de peijnoob
    Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    279
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 279
    Points : 294
    Points
    294
    Par défaut
    Hmm, c'est intéressant ça

    Le .def, je me suis déjà posé des questions à ce sujet, et il me semblait que c'était un fichier généré par le compilo qui permettait à d'autres applis d'utiliser la dll (en important ledit .def)

    Si je comprends bien, c'est l'inverse !! Le .def sera utilisé par le compilateur au moment de la compilation (oui, je sais, je me répète :p) pour définir les ordinaux des fonctions??

    Si c'est cela, ça résoud mon problème (je sais que Dev-C++ supporte les .def, mais Code::Blocks, je sais pas...)

    Merci

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    C'est le .lib qui est généré par le compilo (par l'éditeur de liens, en fait) et qui est inutile si on utilise LoadLibrary() et GetProcAddress().

    Le .lib généré n'est pas un .lib ordinaire (bibliothèque statique), mais une bibliothèque statique d'importation, qui dit au linker que les fonctions sont dans une DLL, et qu'il faudra charger automatiquement la DLL en question lors du démarrage du programme.

  10. #10
    Membre actif Avatar de peijnoob
    Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    279
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 279
    Points : 294
    Points
    294
    Par défaut
    Ok, je crois que je commence à mieux saisir le système.

    j'ai le code source de l'application appelante, mais je ne peux pas y toucher, c'est là tout le problème.

    Elle utilise bien le LoadLibrary et le GetProcAddress, mais pas en se référant aux fonctions suivant leur nom, mais bien par leur ordinal.

    C'est pour cela qu'il faut que je puisse définir moi même cet ordinal, sinon ça ne fonctionnera jamais.

    Et là, on en revient au problème initial... Comment puis-je le définir ??

    Je rame

  11. #11
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 752
    Points : 10 683
    Points
    10 683
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par peijnoob
    Elle utilise bien le LoadLibrary et le GetProcAddress, mais pas en se référant aux fonctions suivant leur nom, mais bien par leur ordinal.
    arf, qui a osé

    Citation Envoyé par peijnoob
    C'est pour cela qu'il faut que je puisse définir moi même cet ordinal, sinon ça ne fonctionnera jamais.

    Et là, on en revient au problème initial... Comment puis-je le définir ??

    Je rame
    via un fichier .def comme on te l'a dit. Je crois qu'avec VC++ on peut utiliser un pragma aussi.

  12. #12
    Membre actif Avatar de peijnoob
    Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    279
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 279
    Points : 294
    Points
    294
    Par défaut
    Wahou, j'ai trouvé !!

    Enfin, j'ai à moitié résolu mon problème

    En fait, lors de l'édition des liens, l'ordinal est attribué à la fonction par rapport à (je vous le donne en mille...) : son orthographe !!!!

    Et oui, ils sont rangés par ordre alphabétique ^^

    Comme je n'avais pas encore défini toutes les fonctions dans ma dll, il y avait un décalage, et du coup, ça ne marchait pas bien.

    Alors, on en vient à mon 2eme problème !!!

    En fait, il n'y a pas une, mais 2 applications qui font appel à ma dll.

    La 1ere, se réfere à elle grace à l'ordinal des fonctions (problème résolu).
    L'autre s'y réfère par rapport au nom. Et là se situe le problème. Le nom décoré pour les fonctions doit être de la forme _MaFonction@0, soit le mot clef __stdcall (j'espère que jusque ici, je ne me trompe pas )

    OR si j'utilise __stdcall comme mot clef, il se passe une chose étrange.. Dev-C++ compile le projet. Je regarde de .def qui en ressort, et là, Ô surprise, je n'ai pas une, mais 2 lignes dans le .def par fonction, du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    EXPORT
      maFonction = _maFonction@8 @1
      _maFonction@8 @2
    Dans ce cas, ça passe bien au niveau de l'application qui utilise les GetProcAddress en fonction du nom, mais celle qui utilise les ordinaux (je sais pas si on dit comme ça, mais ça me paraît logique ) ne fonctionne plus.

    Pour l'instant, mes fonctions sont déclarées comme ceci dans ma DLL :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    DLLIMPORT int __stdcall maFonction (void);
    La commande préproc qui définit le DLLIMPORT est la suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #if BUILDING_DLL
    # define DLLIMPORT __declspec (dllexport)
    #else /* Not BUILDING_DLL */
    # define DLLIMPORT __declspec (dllimport)
    #endif /* Not BUILDING_DLL */
    C'est pas moi qui l'ait écrit, ça, c'est dev-C++ comme un grand

    Je me demandais si la solution n'était pas un truc du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    DLLIMPORT int KEY MaFonction (void);
    On pourrait définir un mot clef pour le .def différent de celui utilisé pour les GetProcAddress qui viennent chercher la fonction par rapport à son nom.

    Mais je ne vois pas trop comment réaliser ceci, étant donné que le préprocesseur, je ne m'y suis jamais trop attelé.

    De plus, je suis loin d'être dûr que ce soit la solution, alors si quelqu'un a une piste, je suis preneur

    Merci à tous

    EDIT : j'ai oublié un mot

  13. #13
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Tu veux dire que Dev-C++ génère un fichier .def?
    Et que se passe-t-il si tu édites toi-même le fichier .def (en retirant la première ligne de chaque couple et en forçant l'ordinal toi-même) ?

  14. #14
    Membre actif Avatar de peijnoob
    Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    279
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 279
    Points : 294
    Points
    294
    Par défaut
    Oui, dev-c++ génère un fichier .def (et un .a par la même occaze)

    J'ai Visual C++ express installé sur mon poste, peut-être qu'il utilise son compilo, je sais pas ^^

    Sinon, oui, j'ai essayé de changer manuellement le .def, mais ça ne change absolument rien. J'ai tout arrangé correctement et inversé les numéros de 2 fonctions. J'ai copié à la place du .def original, mais paf, il m'appelait toujours la même fonction.

    De plus, j'ai pas encore complètement saisi l'utilisation du .def... Pour moi, c'était comme un .a, un truc à importer dans son projet pour pouvoir appeler des fonctions comme si on avait le proto et la définition directement dans le code.

    Et puis, où ce .def doit-il être ?? dans le répertoire de l'application qui appelle la dll ?? dans le répertoire de la dll ? dans un répertoire du path ?? J'avoue que c'est encore un peu obscur de ce côté là.

    Enfin, je vais encore faire quelques tests pour voir. Merci

  15. #15
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 752
    Points : 10 683
    Points
    10 683
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par peijnoob
    En fait, lors de l'édition des liens, l'ordinal est attribué à la fonction par rapport à (je vous le donne en mille...) : son orthographe !!!!

    Et oui, ils sont rangés par ordre alphabétique ^^
    chaque compilo est libre de faire comme il le veut

    Citation Envoyé par peijnoob
    La 1ere, se réfere à elle grace à l'ordinal des fonctions (problème résolu).
    L'autre s'y réfère par rapport au nom. Et là se situe le problème. Le nom décoré pour les fonctions doit être de la forme _MaFonction@0, soit le mot clef __stdcall (j'espère que jusque ici, je ne me trompe pas )
    extern "C" + __stdcall si tu compiles en C++ devrait te donner le name mangling recherché (__stdcall tout seul devrait marcher si tu compiles en C = un fichier .c et pas .cpp).

  16. #16
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 752
    Points : 10 683
    Points
    10 683
    Billets dans le blog
    3
    Par défaut
    Le .def est utilisé au moment de la compilation de la dll, et permet de se passer de mettre des dllexport et consors dans ton code.

  17. #17
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Il a déjà le bon name mangling.
    Mais le fichier .def n'est pas supposé être généré par le compilateur, il est supposé être utiliser par le linker pour savoir ce qu'il doit exactement mettre ou non dans la DLL et dans le .lib/.a.

    Essaie avec les options de Dev-C++ pour modifier le makefile et désactiver la génération automatique du .def, pour forcer le linker à utiliser un .def que tu auras modifié toi-même comme je te l'ai conseillé...

  18. #18
    Membre actif Avatar de peijnoob
    Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    279
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 279
    Points : 294
    Points
    294
    Par défaut
    Ah, là je comprends mieux

    Je vais aller trifouiller les entrailles de dev-c++ pour trouver comment faire.

    Merci encore pour toutes vos réposes

  19. #19
    Membre actif Avatar de peijnoob
    Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    279
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 279
    Points : 294
    Points
    294
    Par défaut
    Oki, je peux spécifier un MakeFile spécifique..

    Mais je suppose que le MakeFile ne correspond pas uniquement au .def

    Sinon, c'est simple, il suffit que je mette mon .def perso et en avant guinguamp, j'ai résolu tous mes problèmes

  20. #20
    Membre actif Avatar de peijnoob
    Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    279
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 279
    Points : 294
    Points
    294
    Par défaut
    Alors, j'ai un peu avancé.

    Vu que je ne suis pas expert en makefile (j'ai lu le tuto sur le site mais un peu en diagonale ^^), j'ai chopé celui que me sort Dev-C++ à la compilation pour le modifier.

    Pour l'instant, j'ai changé le nom du .def utilisé, mais au lieu de prendre celui que j'ai créé, il me l'écrase avec celui qu'il crée lui.

    Je pense que le problème vient de la lignes suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $(DLLWRAP) --output-def $(DEFFILE) --implib $(STATICLIB) $(LINKOBJ) $(LIBS) -o $(BIN)
    C'est ce --output qui m'intrigue, je suppose qu'il dit au compilo de créer le .def, mais je pense pas que c'est juste en supprimant ce --output que ça va résoudre mon problème..

    Pourriez-vous me donner une piste ?

    Merci

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Appel d'une fonction dans une fonction d'une même classe
    Par script73 dans le forum Général Python
    Réponses: 3
    Dernier message: 06/03/2015, 10h18
  2. Réponses: 6
    Dernier message: 02/11/2011, 09h34
  3. portée d'une variable dans une fonction dans une méthode
    Par laurentg2003 dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 29/06/2009, 19h05
  4. [POO] dans une classe, appeler une fonction dans une méthode
    Par arnaudperfect dans le forum Langage
    Réponses: 3
    Dernier message: 26/08/2007, 23h04
  5. [PHP-JS] une fonction dans une fonction
    Par lodan dans le forum Langage
    Réponses: 6
    Dernier message: 25/06/2006, 19h14

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