2010-06-21 14 views
5

Existe-t-il un mécanisme ou une astuce pour exécuter une fonction lors du chargement d'un programme?Pouvez-vous exécuter une fonction à l'initialisation dans c?

Ce que je suis en train de réaliser ...

void foo(void) 
{ 
} 

register_function(foo); 

mais évidemment register_function ne fonctionnera pas.

donc un truc en C++ est d'utiliser l'initialisation pour faire une course de fonction

quelque chose comme

int throwaway = register_function(foo); 

mais cela ne fonctionne pas en C. Je suis à la recherche d'un moyen de contourner cette en utilisant la norme C (spécifique ne plate-forme/compilateur)

+4

Qu'est-ce qui ne va pas avec 'main()'? –

+0

parce que je veux un certain nombre de fichiers. C, et je ne veux pas que les gens doivent se rappeler d'aller mettre la fonction de registre dans la principale .... –

Répondre

14

Si vous utilisez GCC, vous pouvez le faire avec un attribut de fonction constructor, par exemple:

#include <stdio.h> 

void foo() __attribute__((constructor)); 

void foo() { 
    printf("Hello, world!\n"); 
} 

int main() { return 0; } 

Cependant, il n'y a pas de manière portable de faire cela en C.

Si cela ne vous dérange pas de jouer avec votre système de construction, vous avez plus d'options. Par exemple, vous pouvez:

#define CONSTRUCTOR_METHOD(methodname) /* null definition */ 

CONSTRUCTOR_METHOD(foo) 

maintenant écrire un script de compilation pour rechercher des instances de CONSTRUCTOR_METHOD et coller une séquence d'appels à eux en fonction dans un fichier .c généré. Appelez la fonction générée au début de main().

+0

nice, c'est ce que je veux, mais j'espérais quelque chose de plus –

+1

ne pas faire C++ ici, c'est trivialement facile en C++ –

+0

La solution de bdonlan n'utilise pas C++. Relisez-le à nouveau; c'est simplement spécifique au GCC. –

0

Il n'existe pas de méthode standard, bien que gcc fournisse un attribut constructor pour les fonctions.

La manière habituelle d'assurer qu'une pré-configuration a été effectuée (autre qu'une simple initialisation de variable à une valeur de temps de compilation) est de s'assurer que toutes les fonctions nécessitant cette pré-configuration. En d'autres termes, quelque chose comme:

static int initialized = 0; 
static int x; 

int returnX (void) { 
    if (!initialized) { 
     x = complicatedFunction(); 
     initialized = 1; 
    } 
    return x; 
} 

Ceci est mieux fait dans une bibliothèque séparée car il vous isole de l'implémentation.

+0

ouais .... mais dans mon cas, je veux une pré-configuration où une fonction sera enregistrée et stockée dans une liste ..... puis plus tard quelque chose passera par cette liste exécutant les fonctions enregistrées. Actuellement, cela signifie que chaque fonction doit être explicitement ajoutée dans un emplacement central. Je voulais trouver un truc où la fonction peut être enregistrée au moment de la déclaration –

3

La norme C ne prend pas en charge une telle opération. Si vous ne souhaitez pas utiliser les fonctionnalités spécifiques du compilateur pour le faire, alors votre meilleur choix pourrait être de créer un drapeau statique global initialisé à false. Ensuite, chaque fois que quelqu'un invoque l'une de vos opérations nécessitant l'enregistrement du pointeur de fonction, vous vérifiez ce drapeau. Si c'est faux, vous enregistrez la fonction puis définissez l'indicateur sur true. Les appels ultérieurs n'auront alors plus à effectuer l'enregistrement. Ceci est similaire à l'instanciation paresseuse utilisée dans le motif de conception OO Singleton.