Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

128
Views
¿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 answers
Answer question

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!