En realidad, puede hacer casi todo lo que desee. En el lenguaje C (a diferencia de C++, por ejemplo), las funciones en los objetos compartidos se referencian simplemente por sus nombres. Por lo tanto, para encontrar, y lo que es más importante, para llame al --la función adecuada, no necesita su firma completa. ¡Solo necesitas su nombre! Es una ventaja y una desventaja, pero esa es la naturaleza del idioma que eliges.
Déjame demostrar cómo funciona.
#include <dlfcn.h>
typedef void* (*arbitrary)();
// do not mix this with typedef void* (*arbitrary)(void); !!!
int main()
{
arbitrary my_function;
// Introduce already loaded functions to runtime linker's space
void* handle = dlopen(0,RTLD_NOW|RTLD_GLOBAL);
// Load the function to our pointer, which doesn't know how many arguments there sould be
*(void**)(&my_function) = dlsym(handle,"something");
// Call something via my_function
(void) my_function("I accept a string and an integer!\n",(int)(2*2));
return 0;
}
De hecho, puede llamar a cualquier función de esa manera. Sin embargo, hay un inconveniente. De hecho, necesita saber el tipo de retorno de su función en tiempo de compilación. De forma predeterminada, si omite void * en ese typedef, se asume que int es un tipo de retorno, y sí, es un código C correcto. El problema es que el compilador necesita saber el tamaño del tipo de devolución para operar la pila correctamente.
Puede solucionarlo mediante trucos, por ejemplo, precribiendo previamente varios tipos de funciones con diferentes tamaños de tipos de devolución y luego seleccionando a cuál va a llamar en realidad.Pero la solución más fácil es requerir funciones en su complemento para devolver void * o int always; el resultado real se devuelve mediante punteros dados como argumentos.
Lo que debe asegurarse es que siempre llame a la función con el número exacto y los tipos de argumentos que se supone que debe aceptar. Preste más atención a la diferencia entre diferentes tipos de enteros (su mejor opción sería emitirles argumentos explícitamente).
Varios comentadores informaron que no se garantiza que el código anterior funcione para funciones variadas (como printf
).
> Estoy tratando de hacer algo como lo siguiente Entonces, ¿qué ocurre cuando pruebas esto? – a2800276
@ a2800276: el compilador se queja de una multitud de problemas de sintaxis. El problema más profundo es malinterpretar el servicio proporcionado por 'dlopen()' y 'dlsym()', etc. –