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 :

Syntaxe du C !


Sujet :

Windows

  1. #1
    Nouveau membre du Club
    Inscrit en
    Septembre 2005
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 33
    Points : 34
    Points
    34
    Par défaut Syntaxe du C !
    Bonsoir,
    Petite question innocente
    Dans int WINAPI WinMain (HINSTANCE hInstance,..
    (langage C), le WINAPI (__stdcall), il est compatible avec le standard ?
    Je veux dire, le prototype d'une fonction en C c'est :
    type_retourné fonction(args)
    non ?
    Alors ? Le WINAPI, c'est pas un type, si ? C'est une spécificité Windows (comme la signification du __stdcall) ?
    C'est compilable par gcc (qui respecte le standard) ça ?

    Meci d'éclairer ma lanterne

  2. #2
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Points : 1 956
    Points
    1 956
    Par défaut
    Bonjour,

    WINAPI n'est qu'une définition de __stdcall

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #define WINAPI  __stdcall
    
    la plupart de ces #define sont présents dans "Windef.h".

    stdcall (standard call) n'est qu'une convention d'appel pour les fonctions, pour plus d'infos voir :

    http://en.wikipedia.org/wiki/Calling_convention

    Il semble que __stdcall (avec deux underscores) soit une spécificité microsoft mais stdcall devrait être reconnu par GCC.

  3. #3
    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 682
    Points
    10 682
    Billets dans le blog
    3
    Par défaut
    Tout ce qui commence par un (ou 2) undescore est spécifique au compilo.
    http://msdn2.microsoft.com/en-US/lib...93(VS.80).aspx

  4. #4
    Nouveau membre du Club
    Inscrit en
    Septembre 2005
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 33
    Points : 34
    Points
    34
    Par défaut
    Merci pour vos réponses.
    J'ai bien eu du mal pour trouver la signification du __stdcall sur le net, le wiki que tu indique Neitsa est particuièrement explicite !
    Voici la substantifique moelle d'une bonne heure de recherches frustrantes, pour l'intérêt général :

    __cdecl - This is the default calling convention for C and C++ programs. Because the stack is cleaned up by the caller, it can do vararg functions. The __cdecl calling convention creates larger executables than __stdcall, because it requires each function call to include stack cleanup code. WINDOWS.H now supports the WINAPI macro, which translates to the appropriate calling convention for the target (MSDN2).

    Different languages use different calling convention, and if you call a function using an incorrect calling convention, everything breaks. Hard. Not only can arguments get assigned incorrectly, but the stack may fall apart. Either it'll get cleaned twice [resulting in losing memory you think is there], or it won't get cleaned at all [resulting in leaking memory]. Either way, thing'll stop working right away even though an explicit error might not be raised.

    So it is pretty important that you have a way of specifying how you want functions called if using an external library. In this case, the windows API expects __stdcall, while c++ does not. So specifying a c++ function as using __stdcall ensures that when the compiler generates code for that call, it can interface with the API without problems.


    Quelqu'un a vu une macro WINAPI dans windows.h ?! Pas moi..
    Mais bon, je préfère le caonnaître comme une macro qui sera proprement remplacée par le préprocesseur, que comme une violation patente de la syntaxe du C..
    Si c'est spécifique au compilo (donc à celui de M$, confirmation explicite ici : reserved for Microsoft C++), comment se fait-ce que gcc aussi puisse tolérer ? C'est spécifique à GCC aussi ?!
    En tous cas il n'y pas pas d'autre explication, puisque je ne trouve nulles parts de stdcall dans les 554 pages du document ISO-IEC 9899 (C standard, 1999)..

    Non non, i é pas tout comprri le WasF/
    Qu'est-ce que c'est que ces drôles de mots mis un peu partout au mépris de la syntaxe !

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    487
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Juillet 2002
    Messages : 487
    Points : 621
    Points
    621
    Par défaut
    GCC aussi accepte ce type de convention d'appel : http://gcc.gnu.org/onlinedocs/gnat_u...onvention.html

    Même si ce n'est pas standard, ce ne serait pas raisonnable pour un compilateur de ne pas pouvoir appeler les DLL d'API Windows.
    On ne peut pas faire boire un âne qui n'a pas soif.

  6. #6
    Nouveau membre du Club
    Inscrit en
    Septembre 2005
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 33
    Points : 34
    Points
    34
    Par défaut
    Merci NicolasG pour ta précieuse indication !
    Ton lien pointe vers un topic sur Ada ! Mais un chemin tortueux prenant son origine là m'a amené à complètement élucider cette affaire. Attention, voici le fin mot de l'histoire :
    En cliquant névrotiquement sur le lien 'Up' en haut de la page que tu indiques, on se rend compte qu'on est dans le manuel "GNAT, The GNU Ada 95 Compiler". Mais c'est C qui m'intéresse ici. Donc sur la GCC online documentation, je remplace Ada par CPP Manual, et dans la table des matières, après avoir essayé quelques entrées faussement racolleuses (pour le sujet qui nous intéresse ici) une certain 3.7.3 System-specific Predefined Macros, conseille de faire "cpp -dM to see them all" (les system-specific). Seeons them all :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    C:\mesLogiciels\Dev\MinGW32\MinGW\bin\cpp.exe -dM J:\Dev\Ogg\libvorbis-1.1.2\include\vorbis\codec.h | find "stdcall"
    J:\Dev\Ogg\libvorbis-1.1.2\include\vorbis\codec.h:26:21: ogg/ogg.h: No such file or directory
    #define _stdcall __attribute__((__stdcall__))
    #define __stdcall __attribute__((__stdcall__))
    Aha !
    Euh.. non ! Ces quoi ces __attribute__ ??!
    Aller Googlons : __attribute__((__stdcall__)) site:gcc.gnu.org
    --> ici : un certain Mark Mitchell (qui semble savoir de quoi il parle) est entrain de pester sur ces attributes, mal définis/documentés/implémentés, dit-il (on est en 2001 qd-même !). Peu importe, retenons simplement qu'il appelle ça "Prefix attributes". Re-Google : toute la première page de résultats reprend le post de monsieur Mark Mitchell, mais la deuxième contient un lien vers un autre post de la même teneur, mais qui semble plus général (l'espoir fait vivre) : Attribute questions :
    > 2.Do people really use "prefix attributes"? They are undocumented,
    > as far as I can tell.
    ...

    They are documented. See "Attribute Syntax" in the manual.
    Atta ! C'est "Prefix attributes" ou "Attribute Syntax" ?
    Pfff...
    Celui-ci fait référence au "manual", donc M. Mitchell doit nous avoir mal orienté avec sa terminologie.. Re-Re-Google : et là bingo, le premier lien retourné est le bon : 5.26 Attribute Syntax. En haut de cette page, vous voyez le discret : Up: C Extensions ?

    Et bé ça y est, vous y êtes C'est pas du C standard ! Pire :
    Because of infelicities in the grammar for attributes, some forms described here may not be successfully parsed in all cases. There are some problems with the semantics of attributes in C++. For example, there are no manglings for attributes, although they may affect code generation, so problems may arise when attributed types are used in conjunction with templates or overloading. Similarly, typeid does not distinguish between types with different attributes. Support for attributes in C++ may be restricted in future to attributes on declarations only, but not on nested declarators.
    (si cette page du manuel est fraiche, notre Mark Mitchell national n'avait pas tort..)
    Soyez courageux et cliquez sur les Function Attributes : cherchez stdcall (c'est trié par ordre alphabétique) :
    stdcallOn the Intel 386, the stdcall attribute causes the compiler to assume that the called function will pop off the stack space used to pass arguments, unless it takes a variable number of arguments.
    Voilà. C'est une extension du ISO C. Ces extensions existent dans C (pré-standard) et C-Objective. La plupart ont été intégrées dans C++ (en particulier stdcall est standard sous ISO C++ - ISO-IEC 14882). Donc pas de violation de la syntaxe du C, ça en fait tout simplement pas partie, c'est une extension

    Merci à tous et bonne nuit !

  7. #7
    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 682
    Points
    10 682
    Billets dans le blog
    3
    Par défaut
    C'était expliqué dans le lien que je t'ai filé:
    http://msdn2.microsoft.com/en-US/lib...58(VS.80).aspx
    A ma connaissance stdcall n'est pas standard C++.
    La convention d'appel est gérée de manière sytandard via extern : extern "C" par exemple.
    WINAPI est bien défini dans windef.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #define CALLBACK    __stdcall
    #define WINAPI      __stdcall
    #define WINAPIV     __cdecl
    #define APIENTRY    WINAPI
    #define APIPRIVATE  __stdcall
    #define PASCAL      __stdcall

  8. #8
    Nouveau membre du Club
    Inscrit en
    Septembre 2005
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 33
    Points : 34
    Points
    34
    Par défaut
    Ton lien explique la siginification du __stdcall (néttoyage de la stack par l'appelé). Mais n'explique pas comment ça s'imbrique dans la syntaxe C. Ce n'est pas très explicite sur le fait que c'est uen extension..

    D'accord : #define WINAPI __stdcall
    et #define __stdcall ...
    où il est ?!

    La recherche sur "attribute" dans la MSDN ne donne rien qui aide à comprendre .. pire, MSDN parle d'une macro dans windows.h qui n'existe pas !

    Heureusement qu'il y a des projets Open Source où toute la doc est vraiment dispo..

    Pour ce qui est du C++, tu as raison. J'ai parlé trop vite, car je n'ai rien trouvé dans les extension au C++.. la vrai référence en matière de standard est le document ISO et lui seul !

    Combien de "programmeurs windows expérimentés" savent, à votre avis, que le WINAPI qu'ils utilisent tous les jours est une extension du langage (des "function attributes") spécifique au pré/compilateur ?

  9. #9
    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 682
    Points
    10 682
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par WasF/
    Ton lien explique la siginification du __stdcall (néttoyage de la stack par l'appelé). Mais n'explique pas comment ça s'imbrique dans la syntaxe C. Ce n'est pas très explicite sur le fait que c'est uen extension..
    parce qu'il commence par un underscore, le standard C définit que c'est une extension. Note aussi que la page du lien commence par:
    Microsoft Specific
    D'accord : #define WINAPI __stdcall
    et #define __stdcall ...
    où il est ?!
    c'est pas un define, c'est un mot-clé spécifique, reconnu par le compilo comme un if, un else ou un struct.

    La recherche sur "attribute" dans la MSDN ne donne rien qui aide à comprendre .. pire, MSDN parle d'une macro dans windows.h qui n'existe pas !
    Parce que Microsoft appelle ça des modifiers:
    http://msdn2.microsoft.com/en-US/lib...4z(VS.80).aspx
    attribute, c'est le jargon g++ il me semble.

    Combien de "programmeurs windows expérimentés" savent, à votre avis, que le WINAPI qu'ils utilisent tous les jours est une extension du langage (des "function attributes") spécifique au pré/compilateur ?
    j'ai peur qu'il s'agisse de la majorité. WINAPI est une simple macro, qui n'a rien de spécifique. Ce qui l'est, c'est sa définition. Le but de cette macro est de s'affranchir des spécificités du compilateur. Chez MS elle sera définie en __stdcall, si l'équivalent de __stdcall pour un autre compilateur c'est __badaboum__, ce compilo définira WINAPI en __badaboum__. Bien que chaque compilo ait ses propres extensions, un même code compilera sur l'un ou l'autre grâce à cette macro qui est commune à tout le monde.

  10. #10
    Nouveau membre du Club
    Inscrit en
    Septembre 2005
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 33
    Points : 34
    Points
    34
    Par défaut
    Manque de bol, je crois que je suis tombé sur un "développeurs windows expérimenté" là (un vrai )..
    En tous cas, je le regrette pas ! Merci pour toutes ces explications éclairées !

    Hors-sujet :
    Je trouve ça quand-même rageant que tous des bouquins sur la programmation Windows (en tous cas ceux sur lesquels je suis tombé, en particulier le fameux Programming Windows) semblent s'être inscrits dans un concours pour présenter ce WINAPI de la façon la plus discrète, courte et confuse possible !!
    Quand en plus c'est dans le premier chapitre, .. tu te dis, c'est un complot.
    S'attendent-ils à ce que les apprentis-programmeurs (qui sont à priori des scientifiques, donc des gens curieux et précis ) étouffent leur besoin fondamental de comprendre jusqu'à ce qu'ils deviennent suffisament "mûrs" pour s'attaquer à ces "notions de haut-vol" ?! Pédagogie zéro..

  11. #11
    mat.M
    Invité(e)
    Par défaut
    Citation Envoyé par WasF/
    D'accord : #define WINAPI __stdcall
    et #define __stdcall ...
    où il est ?!
    Si tu utilises VC++, sélectionner "WINAPI" et d'un clic-droit ->popmenu et sélectionner "WINAPI définition".
    Le fichier windef.h est ouvert


    Les mots-clés réservés comme _stdcall et _cdecl indiquent au compilateur la manière dont sont passés les arguments à une fonction.
    Par exemple en Pascal c'est l'inverse du C:les premiers paramêtres d'abord ;
    il faut avoir fait de l'assembleur pour comprendre cela.

  12. #12
    CGi
    CGi est déconnecté
    Expert éminent
    Avatar de CGi
    Inscrit en
    Mars 2002
    Messages
    1 042
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 1 042
    Points : 8 252
    Points
    8 252
    Par défaut
    en _stdcall c'est la fonction applée qui supprime les paramètres de la pile,
    alors qu'en _cdecl c'est à la fonction appelante qui doit supprimer les les paramètres de la pile.
    en pascal c'est comme la _stdcall et qu'en plus les paramètres sont inversé comme l'a dit mat.M
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

  13. #13
    mat.M
    Invité(e)
    Par défaut
    Merci pour les infos je ne savais pas

  14. #14
    Nouveau membre du Club
    Inscrit en
    Septembre 2005
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 33
    Points : 34
    Points
    34
    Par défaut

    J'ai VC++ 2005 Express, et en faisant un clique droit sur un mot, j'ai directement un "Go to definition", très très pratique. J'en use et abuse..
    Au boulot, j'ai vu sur l'écran d'un développeur Java qu'Eclipse permettait carrément de cliquer sur les nom des objet comme sur un lien HTML..

    Sur le Wiki proposé par Neitsa, j'ai découvert que ces conventions d'appel faisaient partie de l'ABI (Application Binary Interface), qui décrit aussi les n° des appels système et le format des fichiers objet ...

Discussions similaires

  1. [syntaxe] Gerer les variables dans une requete
    Par rastapopulos dans le forum MS SQL Server
    Réponses: 12
    Dernier message: 15/04/2003, 12h53
  2. Syntaxe requete
    Par Chipolata dans le forum Langage SQL
    Réponses: 2
    Dernier message: 28/03/2003, 14h22
  3. [Syntaxe] Action simultanée sur plusieurs élements
    Par FranT dans le forum Composants VCL
    Réponses: 2
    Dernier message: 20/03/2003, 20h20
  4. Syntaxe TASM <-> MASM
    Par LFC dans le forum Assembleur
    Réponses: 3
    Dernier message: 28/02/2003, 15h56
  5. [VB6] [Syntaxe] Fonction renvoyant un tableau d'objets
    Par Troopers dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 18/10/2002, 15h33

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