Définir un point d'entrée [Résolu]

cs_Havy 7 Messages postés dimanche 12 juillet 2009Date d'inscription 12 août 2009 Dernière intervention - 12 juil. 2009 à 15:22 - Dernière réponse : cs_Havy 7 Messages postés dimanche 12 juillet 2009Date d'inscription 12 août 2009 Dernière intervention
- 20 juil. 2009 à 19:39
Bonjour, sachant que tout programme console doit contenir la fonction main pour fonctionner, car c'est le point d'entrée, je voudrais savoir s'il est possible de définir son propre point d'entrée.

Par exemple je voudrais faire ceci :

#include

using namespace std;

void Test()
{
}

Et donc, faire en sorte que quand je compile, il n'y'a pas référence à main mais à Test comme fonction principale pour faire démarrer le programme.

J'ai fais des recherches concernant la directive #pragma et entry, mais je n'ai rien trouvé qui pourrait m'aider.

NB : J'utilise Dev-C++ si cela peut aider :)

Merci d'avance pour votre aide, passez une bonne journée et bonne prog ;)
Afficher la suite 

Votre réponse

3 réponses

Meilleure réponse
cs_rt15 3982 Messages postés mardi 8 mars 2005Date d'inscription 7 novembre 2014 Dernière intervention - 18 juil. 2009 à 22:52
3
Merci
Salut,

Alors en fait, dans un fichier .exe, il y a un point d'entrée "entry point". C'est une adresse définie dans le header du fichier exécutable, au milieu d'autres infos :

OPTIONAL HEADER VALUES
     10B magic #
    8.00 linker version
   12E00 size of code
   18800 size of initialized data
       0 size of uninitialized data
   126FE address of entry point
    1000 base of code


Quand on demande à Windows d'exécuter un programme, il charge en mémoire le contenu du .exe, en mappant les sections de celui-ci à divers emplacement, en se basant sur les infos dans le header. Puis il charge les dll nécessaires (Précisées dans une table elle aussi accessible via le header), et résous les adresses des fonctions importées. Il appelle aussi les point d'entrée de ces dlls.

Et finalement, le programme démarre "réellement" quand le point d'entrée du .exe est appelé.

Mais quel code ce trouve ici ? Le code du main compilé ? NON !
Il y a le code d'initialisation de la runtime, qu'elle soit C ou C++.

En effet, pour pouvoir fonctionner, la CRT a besoin d'une phase d'initialisation, et d'une phase de libération, avant et après le main. C'est là que va d'ailleurs se faire la préparation de argv et argc, qui ne sont pas passé en argument du vrai point d'entrée (Il n'a pas d'arguments pour un .exe).

La CRT est une librairie comme une autre (Dans le cas de gcc, il s'agit de la glibc), qui fournit toutes les fonctions de base du standard C (printf, fopen, system, malloc, strcat...), sauf qu'elle est dans le chemin du lieur par défaut (-lC par défaut quoi). Pour le C++, le principe doit être similaire. Le C++ est forcé d'exécuter du code caché lui aussi, en plus de celui du C (Des exécution de constructeurs notamment).

Mais la particularité de cette librairie, donc, c'est qu'elle appelle le main. Au vrai point d'entrée du .exe, ont trouve quelques chose comme ça (C'est pas du tout comme ça mais c'est l'esprit, dans le cas d'une appli console) :

/* Déclaration du main */
int main(int argc, char** argv);

int __cdecl WinMainCRTStartup()
{
  int nResult;
  InitCrt();
  nResult = main(GetArgC(), GetArgV());
  FreeCrt();
  return nResult;
}


Comment le linker sait-il quelle adresse mettre comme entry point dans le header ? Il met l'adresse de WinMainCRTStartup (Appli gui) ou de mainCRTStartup (Appli console). C'est codé en dur dans le linker ! La CRT définie ces deux symboles donc quoiqu'il arrive, ils sont trouvés au link.

Par contre quand on oublie de définir un main, pouf, le linker n'est pas content, car il ne trouve pas l'implémentation de la fonction main appelée par le code d'initialisation de la CRT (WinMain dans le cas d'une appli GUI).

Première constatation... Si on veut définir son propre point d'entrée, la CRT n'est pas initialisée ! Bilan, définir son propre point d'entrée, s'est aller au devant de très gros ennui si on utilise des fonctions standard... Par contre, avec windows.h par exemple, pas de soucis !

Bon, donc supposons que l'on décide de ne pas utiliser la lib standard...

Il faut donc, par exemple pour une appli GUI, se débarrasser de la CRT en entrée du lieur, et définir WinMainCRTStartup (Méthode qui marche pour VC et gcc donc plus portable que le /entry). Exemple de code :
#include "windows.h"

int __cdecl WinMainCRTStartup()
{
  MessageBox(NULL, "Je n'ai pas de CRT", "Point d'entrée custom", MB_OK);
  return 0;
}


Ce code n'inclus que windows.h, donc on ne touche pas à la CRT.

Pour compiler, on demande à gcc de ne pas utiliser les libs par défaut :
-nostartfiles -nodefaultlibs -nostdlib pour gcc
/NODEFAULTLIB pour VC

Par contre faut ajouter manuellement d'éventuelles librairies par défaut manquante du coup (Ici, MessageBox est dans user32) ->
gcc -Wall -ansi -pedantic test.c -o test.exe -nostartfiles -nodefaultlibs -nostdlib -luser32

Et nous voilà avec un superbe .exe de 5ko, sans initialisation et libérations inutile... Bref une bête de course très propre.

Merci cs_rt15 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 94 internautes ce mois-ci

Commenter la réponse de cs_rt15
cs_juju12 968 Messages postés samedi 3 avril 2004Date d'inscription 4 mars 2010 Dernière intervention - 12 juil. 2009 à 17:22
0
Merci
oui.

Sous Visual C++ Express (mais je pense que ça t'aidera pas)

#pragma comment(linker,"/entry:Test")


du moins, tu sais que c'est possible maintenant.
Commenter la réponse de cs_juju12
cs_Havy 7 Messages postés dimanche 12 juillet 2009Date d'inscription 12 août 2009 Dernière intervention - 20 juil. 2009 à 19:39
0
Merci
Je vous remercie beaucoup pour toutes ces infos, je vais travailler sur tout ça :)

Encore merci et passez une bonne journée ;)
Commenter la réponse de cs_Havy

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.