Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

117
Visualizações
¿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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda