2010-06-21 20 views
5

¿Hay un mecanismo o truco para ejecutar una función cuando se carga un programa?¿Se puede ejecutar una función en la inicialización en c?

Lo que estoy tratando de lograr ...

void foo(void) 
{ 
} 

register_function(foo); 

pero obviamente register_function no se ejecutará.

por lo que un truco en C++ es el uso de inicialización para realizar una función de ejecución

algo así como

int throwaway = register_function(foo); 

pero eso no funciona en C. Así que estoy buscando una forma de evitar esto utilizando el estándar C (nada plataforma/compilador específico)

+4

¿Qué pasa con 'main()'? –

+0

porque quiero un número de archivos .c, y no quiero que la gente tenga que recordar ir a poner la función de registro en el principal .... –

Respuesta

14

Si se está empleando gcc, se puede hacer esto con un atributo constructor función, por ejemplo:

#include <stdio.h> 

void foo() __attribute__((constructor)); 

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

int main() { return 0; } 

Sin embargo, no existe una forma portátil de hacerlo en C.

Si no te molesta jugar con tu sistema de compilación, tienes más opciones. Por ejemplo, se puede:

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

CONSTRUCTOR_METHOD(foo) 

Ahora escribe un script de construcción para buscar instancias de CONSTRUCTOR_METHOD, y pegar una secuencia de llamadas a ellos en una función en un archivo .c generado. Invoque la función generada al comienzo de main().

+0

bueno, es lo que quiero, pero esperaba algo más estándar C –

+1

sin hacer C++ aquí, es trivialmente fácil en C++ –

+0

La solución de bdonlan no usa C++. Lea de nuevo; es simplemente específico de GCC. –

0

No hay una forma estándar de hacerlo, aunque gcc proporciona un atributo constructor para las funciones.

La forma habitual de garantizar que se haya realizado una configuración previa (que no sea una inicialización de variable simple a un valor de tiempo de compilación) es asegurarse de que todas las funciones requieren esa preconfiguración. En otras palabras, algo como:

static int initialized = 0; 
static int x; 

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

Esto se realiza mejor en una biblioteca separada ya que lo aísla de la implementación.

+0

sí ... sin embargo, en mi caso, quiero una preconfiguración en la que una función se registre y almacene en una lista ... luego, algo pasará por esa lista ejecutando las funciones registradas. Actualmente eso significa que cada función debe agregarse explícitamente en alguna ubicación central. Quería encontrar un truco donde la función se pueda registrar en el momento de la declaración –

3

La norma C no es compatible con una operación de este tipo. Si no desea usar características específicas del compilador para hacer esto, entonces su siguiente mejor opción podría ser crear una bandera estática global que se inicialice en falso. Luego, cada vez que alguien invoque una de sus operaciones que requiera que se registre el puntero de la función, verifique ese indicador. Si es falso, registra la función y establece el indicador en verdadero. Las llamadas subsiguientes no tendrán que realizar el registro. Esto es similar a la instanciación perezosa utilizada en el patrón de diseño de OO Singleton.

Cuestiones relacionadas