Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

125
Vistas
¿Existe algo así como un puntero de función genérico en C que pueda asignarse/transmitirse a un prototipo más restrictivo?

Tengo la necesidad de vincularme dinámicamente con una biblioteca en tiempo de ejecución y resolver una serie de funciones usando dlsym . Mi primer pensamiento fue usar una matriz de punteros de función que se pueden iterar fácilmente aprovechando una matriz secundaria de caracteres char * que representan los nombres de los símbolos.

Sin embargo, el problema con esto es que no todas las funciones toman los mismos argumentos. ¿Hay alguna manera de usar un puntero de función genérico en la matriz, pero asignarlo a un prototipo de puntero de función más restrictivo? Por ejemplo:

Si necesito resolver estas funciones:

 int (*functionA)(int) char (*functionB)(char,int)

¿Es posible hacer algo como (pseudo-ish ..)

 void* functionList(...)[2] = {functionA, functionB};

Junto con

 char FuncNameA[] = "functionA"; char FuncNameB[] = "functionB"; char *functionNames[2] = {FuncNameA, FuncNameB};

Con el fin de recorrer la llamada a dlsym para la resolución de símbolos

 int i = 0; for(; i<2; i++) functionList[i] = dlsym(DL_OPEN_HANDLE, functionNames[i]);

Donde DL_OPEN_HANDLE estaría definido por una llamada anterior a dlopen .

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

El estándar C garantiza que cualquier tipo de puntero de objeto se puede convertir en void* y viceversa sin pérdida de información (lo que significa que el puntero reconvertido será igual al original).

Existe una garantía diferente para los punteros de función: cualquier puntero de función se puede convertir en cualquier otro tipo de puntero de función y viceversa sin pérdida de información.

(No hay garantía con respecto a las conversiones entre punteros de función y punteros de objeto, o más específicamente entre punteros de función y void* . Una implementación podría, por ejemplo, hacer void* 64 bits y punteros de función 128 bits).

Puede usar, por ejemplo, void(*)(void) como un tipo de puntero de función genérico:

 typedef void (*funcptr)(void);

Debe volver a convertir al tipo de puntero original antes de ejecutar una llamada para evitar un comportamiento indefinido.

Por otro lado, está usando dlsym() , que devuelve un void* . Tengo entendido que POSIX garantiza que el void* devuelto por dlsym() (si el argumento del name nombra una función) se puede convertir en un puntero de función, que se puede usar para llamar a la función. Si las únicas funciones que le interesan son aquellas cuyas direcciones son devueltas por dlsym() , entonces puede usar void* .

(POSIX garantizó anteriormente, como una extensión del estándar C, que un puntero de función se puede convertir en void* y viceversa. Esa garantía se eliminó más tarde. Gracias a Jonathan Leffler por señalar esto).

En cualquier caso, el uso de punteros de función para almacenar las direcciones de las funciones probablemente hace que el código sea más claro.

over 4 years ago · Santiago Trujillo Denunciar

0

dlsym devuelve un puntero de datos de tipo void * , pero POSIX garantiza que esto se puede convertir en un puntero de función del tipo apropiado:

Las implementaciones que admiten la extensión XSI [...] requieren que un objeto de tipo void * pueda contener un puntero a una función. Sin embargo, el resultado de convertir un puntero a una función en un puntero a otro tipo de datos (excepto void * ) aún no está definido.

Desde la versión 7 de POSIX, todas las implementaciones (no solo XSI) son necesarias para admitir la conversión.

Debido a que la conversión de un puntero void * a un puntero de función a través de una conversión directa puede generar advertencias del compilador, las versiones anteriores de POSIX recomiendan realizar la conversión a través de alias:

 int (*fptr)(int); *(void **)(&fptr) = dlsym(handle, "my_function");

En la versión actual, la recomendación se cambia a:

 int (*fptr)(int); fptr = (int (*)(int))dlsym(handle, "my_function");
over 4 years ago · Santiago Trujillo Denunciar

0

Probablemente debería definir su lista como void *functionList[2] , ya que dlsym devuelve un void * . Una vez que sepa qué función tiene, puede convertirla en el tipo adecuado.

 void *functionList[2]; ... int (*functionA)(int) = (int(*)(int))functionList[0]; char (*functionB)(char,int) = (char(*)(char, int))functionList[1];
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda