CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

[C] exécuter du code avant le main()

dnob700
dnob700
Niveau 10
25 août 2007 à 16:09:13

Bonjour,

Mon problème est en C sous linux, mais peut-être qu´il existe une réponse ne dépendant pas du système d´exploitation :

J´écris une bibliothèque qui sera lié statiquement avec des programmes (donc .a), et pour que ça fonctionne il faut que la bibliothèque exécute du code avant que le programme ne rentre dans la fonction main.

Une solution c´est de faire comme la SDL sous windows, i.e. de définir un main dans la bibliothèque, puis dans le fichier d´en tête de la bibliothèque faire un define du type :

  1. define main faux_main

et d´appeler la fonction faux_main dans le main de la bibliothèque.
Mais c´est affreusement moche, ça oblige à inclure le fichier d´en tête de ma bibliothèque dans le fichier du programme qui contient le main, ça force la forme et le nombre d´argument de la fonction main et c´est incompatible avec une autre bibliothèque qui ferait la même chose.

Bref, j´aimerais savoir si vous connaissez une meilleure méthode.

merci d´avance.

LGV
LGV
Niveau 28
25 août 2007 à 17:00:26

tu peux te reposer sur le CRT, qui va parser toutes les inits "statiques" (qui seront effectuees avant le main), ou par aussi par ex. changer le start-up code.

il y a plusieurs approches selon les cas, difficile d´en privilegier une plus qu´une autre sans en savoir plus.

godrik
godrik
Niveau 30
25 août 2007 à 18:55:19

Il me semble qu´en C++ (donc c´est pas exactement ce que tu veux) tu peux ecrire du code pour initialiser les variables statiques. Le langage assure que le code aura été exécuté avant le main. (a confirmer)

Fvirtman
Fvirtman
Niveau 10
25 août 2007 à 19:04:26

Pour executer du code avant l´appel du main, je dirais :
une instance de classe globale.

En effet, si, par exemple, tu fais une classe "plouf"
que, dans ton constructeur par défaut de plouf, tu mets un printf("bonjour"),
si tu mets, en variable globale :

plouf test;

tu verras que le programme écrira bonjour avant la premiere instruction du main (si tu mets un printf("ok") au début du main, tu auras d´abord le bonjour.

C´est une idée si tu veux...

Sachant que pareil, le destructeur de plouf sera appelé apres la derniere instruction du main.

Fvirtman
Fvirtman
Niveau 10
25 août 2007 à 19:05:05

Ah oui, par contre, j´avais mal lu que c´était du C et non du C++.
Hum, cela semble plus complexe du coup...

dnob700
dnob700
Niveau 10
26 août 2007 à 00:36:09

S´il n´y a pas d´autre moyen, j´utiliserais une instance statique de classe (mais ça me gène toujours d´utiliser une classe quand il n´y a qu´un seule instance).

Par contre, LGV, est-ce que tu pourrais développer un peu ce qu´est le start-up code s´il te plaît ?

kufa
kufa
Niveau 9
26 août 2007 à 15:03:21

en C, a ma connaissance on ne peut pas appeler une fonction avant le main, sans modifier le startup code.
Pour reference:
http://msdn2.microsoft.com/en-us/library/abx4dbyh(VS.80).aspx
Tu as le code source, et tu peux recompiler le CRT, et y inserer ce que tu veux avant le main. Bon amusement cela dit.. te sous linux avec gcc, heu pas la moindre idee sorry. ca doit se faire sans "aucun soucis" d´une facon similaire.

En c++, bcp plus facile, mais ce n´est pas le topic ici afaik.

Bon, je sais je vais faire mon chieur, mais je pense qu´avoir a initialiser qqchose avant le main est en general un probleme de design. Par exemple, je ne veux pas qu une lib sur laquelle je link me change mon startup code, ou utilise son propre mem manager, etc. bcp trop intruisif, et souvent cause de bugs diffice sa debugger (par ex l´ordre d´execution des routines de terminaison, cf destructeurs de singletons en c++). Il est bcp plus simple et propre imo d´avoir un struct MyLibContext* MyLib_CreateContext().

/k

godrik
godrik
Niveau 30
26 août 2007 à 15:12:11

pour aller dans le sens de kufa. Cela risque en plus de poser probleme si deux libs ont le meme comportement.

dnob700
dnob700
Niveau 10
26 août 2007 à 23:24:23

"pour aller dans le sens de kufa. Cela risque en plus de poser probleme si deux libs ont le meme comportement."

Je suis d´accord, c´est pour ça que modifier la crt ne me semble pas une bonne idée dans ce genre de cas.

Pour l´instant je l´ai écrit avec 3 ligne en C++ avec une instance statique d´une classe dont le constructeur ne fait qu´appeler une fonction qui lui est passée en argument.

C´est peut-être moins propre qu´autre chose, mais j´essaie toujours de privilégier la simplicité pour l´utilisateur de la bibliothèque. Et comme par nature pour cette bibliothèque il ne peut pas y avoir plusieurs contexte simultanément, il aurait suffit d´une fonction "void MyLib_Init()", mais je trouve ça inutile de demander à l´utilisateur d´appeler une fonction qu´il voudra de toute manière toujours appeler au démarrage de son programme s´il link ma bibliothèque à son programme.

godrik
godrik
Niveau 30
26 août 2007 à 23:36:49

Il pourrait ne pas vouloir l´appeler tout de suite. Ou bien libérer les allocations mémoire a un moment parcequ´il n´en a plus besoin...

kufa
kufa
Niveau 9
26 août 2007 à 23:48:42

ok, tu avais donc possibilite d implementer en c++ :)

Sinon oui je suis tout d´accord avec toi, si tu cherches de la simplicite, tout faire automatiquement c´est nickel. Si tu cherches a faire propre, ++godrik et je m´explique un peu plus sur pourquoi je trouve qu un appel a une fonction est interessant:

en fait cet appel s´avere etre tres utile: par exemple, si l´utilisateur veut forcer la librairie a utiliser son gestionnaire de memoire (par exemple via un param a la fonction);

ou encore si il veut s´assurer d avoir un joli message d erreur si l´init de la lib plante (par exemple passage vista ou nouvel os, un driver utilise par la lib qui plante, etc). Pouvoir gerer les erreurs d´init est qqchose d´important, et laisser cette possibilite a l´utilisateur d´une lib est a mon avis extremement important. Juste avoir un init qui plante avant le main, pas pratique..

D´une facon plus metaphysique, mon opinion reste qu´une library doit faire qqchose quand on lui demande de le faire, et non pas rajouter des threads au demarrage, fragmenter ma memoire, ouvrir un handle sur un directory et le garder, etc. A l´eventuelle exception des lib de gestion de memoire (et encore)

Petite annedocte qui ressemble un peu a ce dont je parle: sur mon dernier projet, on devait utiliser <nom d´une technologie tres connue qui force a avoir le cd du jeu dans le lecteur pour pouvoir jouer>. C´est du code injecte dans l´exe deja pret, chgt d entry point, donc tout se passe meme avant l´init de la CRT. Sauf que.. 15% de plantages sur certaines configs, et beau crash windows. Sans le gestionaire d´erreur (exception handler etc) du main, pas de joli message box avec callstack. Vraiment pas amusant a debugger.

Mais bon la je diverge pas mal du sujet initial, qui semble resolu avec l´instance statique en cplouchplouch :)

/k

Sous forums
  • Aide à l'achat Mac
  • Macintosh
  • Création de Jeux
  • Programmation
  • Création de sites web
  • Linux
  • Internet
  • Steam Deck
  • Hardware
La vidéo du moment