Creo que no se puede invocar una función estática en un archivo fuente directamente desde fuera del archivo. Sin embargo, si de alguna manera logro obtener un puntero a esta función en otro archivo, ¿puedo entonces llamar a esta función desde ese archivo? En caso afirmativo, ¿hay algún escenario en el que nos gustaría tomar esta ruta en comparación con simplemente hacer que la función no sea estática?¿Se puede llamar a una función estática a través de un puntero de función en C?
Respuesta
Sí, puede exportar funciones estáticas entregándoles punteros. Este es un medio común de implementar el Factory pattern en C, donde puede ocultar las implementaciones de un conjunto completo de funciones de los módulos que las usan, y tiene un FuncPtr_t GetFunction(enum whichFunctionIWant)
que las distribuye a los consumidores. Así es como funcionan muchas implementaciones de dynamic linking.
Sí, una función no estática en su archivo puede devolver un puntero a una función estática a cualquier lugar que desee.
Sin embargo, si de alguna manera logro obtener un puntero a esta función en otro archivo, ¿puedo entonces llamar a esta función desde ese archivo?
Sí, es perfectamente posible. La función no es visible para el enlazador, pero está allí en el ejecutable. Siempre puede saltar a su dirección.
Aunque no estoy seguro de los escenarios. Tal vez quieras que los demás solo llamen a tu función después de llamaron a alguna otra función (no estática, por supuesto). Entonces los tiene y lo obtiene, y luego pueden llamarlo.
Sí, puedes. Si tiene que llamar a una función que espera un puntero a una función como devolución de llamada, puede usar estática para que el símbolo de la función no contamine el espacio de nombres global y no provoque conflictos entre los enlazadores. El ejemplo más usado es probablemente qsort:
struct Data { ... };
static int compareData(const void* a, const void* b) { /* cast to Data and compare */ }
...
qsort(array, count, sizeof(Data), &compareData);
Como el otro mencionado, puede hacerlo. Un ejemplo de por qué es deseable es para algún tipo de "controlador". Puede devolver una estructura que contiene las funciones abrir, cerrar, leer y escribir sin tener que hacer que las funciones reales sean accesibles al público.
Sí se puede, siempre se puede probar por ti mismo y saber:
Archivo1.c
#include <stdio.h>
void call_hello(void (*fptr)(void));
static void hello(void) {
puts("hello");
}
int main(void)
{
void (*fptr)(void) = hello;
call_hello(fptr);
return 0;
}
Archivo2.c
void call_hello(void (*fptr)(void))
{
fptr();
}
A menudo no es un buen enfoque en C. "Funciona" y "es seguro, funcionará en todas partes, y no se basa en un comportamiento indefinido" a menudo son cosas muy diferentes. –
A menudo es útil para definir una pequeña función estática como función de trabajo para otra. Mire la norma qsort
para un ejemplo: espera una función de comparación, y muy a menudo es mejor hacer esa función de comparación estática (por ejemplo, porque no es útil en ninguna otra parte, y porque qsort
quiere que tenga alguna firma poco bonita).
- 1. Llamar a una función virtual estáticamente a través de un puntero a la función
- 2. Un puntero a una función encuadernada solo se puede usar para llamar a la función
- 3. ¿Cómo llamar a través de un puntero de función miembro?
- 4. Llamar C++ puntero de función de C#
- 5. Fallo de segmentación al acceder a una estructura-función estática a través de puntero devuelto
- 6. Llamar a una función con un puntero no const se restituye a una función de plantilla sobre una función tomando un puntero a const
- 7. Inicializar Puntero A través de la función
- 8. Llamar a un ++ puntero de función miembro de C: este puntero se corrompe
- 9. Sintaxis para un puntero a una función que devuelve un puntero de función en C
- 10. Llamar a una función a través de su dirección en la memoria en c/C++
- 11. En C++ puede tener un puntero a una función, ¿También puede tener un puntero a una clase?
- 12. ¿Cómo paso un puntero a una función c en Cython?
- 13. Llamar a un puntero de función C++ en una instancia de objeto específico
- 14. No se puede llamar a un método de Objective C desde una función C
- 15. Pasar la función puntero a miembro como puntero a función
- 16. C: puntero a función en línea
- 17. Puntero de función a función de miembro
- 18. Puntero de función que apunta a una función que toma un puntero de función
- 19. Llamar a una función MATLAB desde C#
- 20. ¿Función para llamar a una función repetidamente?
- 21. C# función de puntero en función sobrecargada
- 22. Llamar a una función de una cadena en C#
- 23. ¿Cómo declaras un puntero a una función que devuelve un puntero a una matriz de valores int en C/C++?
- 24. C: ¿Cómo pasar un doble puntero a una función
- 25. ¿Cómo puede llamar una función de args variables a otra?
- 26. WebKit.NET para llamar a una función de C# desde JavaScript
- 27. Llamar a una función de biblioteca C++ en vimscript
- 28. Puntero de función C#?
- 29. ¿Cómo puedo llamar a una función de SQL en C#?
- 30. ¿Cómo puedo escribir una función C genérica para llamar a una función Win32?
Me pregunto cuál es el comportamiento si se mezcla esto con la palabra clave 'inline' y/o las directivas propietarias del compilador que siempre alinearían una función. – mpontillo
@mpontillo Creo que incluso si la función está marcada como 'en línea' pero la dirección se toma en un puntero a función, el compilador generará el cuerpo en el binario, al tiempo que lo contextualizará en otras funciones en el mismo módulo. –