Estoy creando una biblioteca de bajo nivel que requiere inicialización para funcionar correctamente, que implementé con una función de inicio. Me pregunto si hay una manera de hacer que se llame a la llamada de inicio una vez que el usuario llama a una función de biblioteca idealmente sin:
mi solución actual según la solicitud de comentario:
bool isinit = 0; void init() { isinit = 1; // init code } void lib_function() { if(!isinit) init(); // function code }El compilador parece ser lo suficientemente inteligente (usando -0fast en gcc) para no hacer esa comparación cada vez que se llama a lib_function, pero esto aún expone una variable global que no me gusta.
Si está satisfecho con una solución que es una extensión común en lugar de parte del estándar C, puede marcar su función de inicio con el atributo de constructor, lo que garantiza que se llamará automáticamente durante la inicialización del programa (o durante la carga de la biblioteca compartida si eventualmente termine usando eso).
¿La mejor manera de abstraer una función de inicio?
Seguro que tu biblioteca tiene algún estado. Por lo general, una biblioteca expone funciones que funcionan en una estructura específica. No use variables globales, no escriba código espagueti. Exponga la estructura que contiene el estado de su biblioteca y haga que todas las funciones de su biblioteca tomen un puntero a la estructura como argumento. Use un espacio de nombres: agregue un prefijo a todos los símbolos exportados. Una función de inicio es como int lib_init(struct lib_the_struct *t); - Será comprensible que los usuarios necesiten inicializar la estructura con esa función antes de usarla. Por ejemplo: fopen() , pthread_create .
Escriba una función de inicio en su biblioteca. Escriba una documentación clara que indique que el usuario de su biblioteca debe llamar a la función una vez antes de llamar a cualquier otra función. Por ejemplo: https://curl.se/libcurl/c/curl_global_init.html .
Arreglaría esto con afirmación para que desaparezca en la compilación de lanzamiento y si olvida llamar a la función init en algún lugar, obtendrá el error durante el desarrollo.
También convierta isinit en estático para que cada biblioteca pueda tener su propia variable con el mismo nombre.
#include <assert.h> #ifndef NDEBUG static int isinit = 0; #endif void lib_function() { assert(isinit && "library: init not called"); }