Test Foro de elhacker.net SMF 2.1

Programación => Programación C/C++ => Mensaje iniciado por: 0xDani en 7 Agosto 2012, 20:37 PM

Título: Problema con dlfcn.h.
Publicado por: 0xDani en 7 Agosto 2012, 20:37 PM
Bueno estoy intentando usar funciones de librerias dinamicas sin hacer un include, y he encontrado un ejemplo en el que se consigue esto en una pagina de documentacion de dlfcn.h(pubs.opengroup.org/onlinepubs/7908799/xsh/dlsym.html). El problema es que he intentado hacer algo similar con una funcion que recibe dos enteros y retorna su suma y no me termina de salir.
Aqui esta el codigo:
#include <iostream>
#include <dlfcn.h>

using std::cout;

int main()
{
    int a=2, b=3;
    int fptr(int, int);
    void* handle = dlopen("libprueba.so", RTLD_LAZY);
    fptr = (int(int, int))dlsym(handle, "SampleAddInt");
    int c = fptr(a, b);
    cout << c;
    dlclose(handle);
    return 0;
}

Este es el contenido de libprueba.so:
int SampleAddInt(int i1, int i2)
    {
        return i1 + i2;
    }

Y el error que me da el compilador es cuando le intento asignar a fptr el resultado de dlsym, me dice conversion invalida al tipo de funcion 'int(int, int)'.
¿Como lo puedo solucionar? Debe de haber alguna manera de realizar la conversion.

Saludos.
Título: Re: Problema con dlfcn.h.
Publicado por: Eternal Idol en 7 Agosto 2012, 22:18 PM
Código (c++) [Seleccionar]
int (*fptr)(int, int) = (int(*)(int, int))dlsym(handle, "SampleAddInt");

Aunque yo preferiria:
Código (c++) [Seleccionar]
typedef int (*SampleAddInt_ptr)(int,int);
...
SampleAddInt_ptr SampleAddInt = (SampleAddInt_ptr)dlsym(handle, "SampleAddInt");
int c = SampleAddInt(a, b);
Título: Re: Problema con dlfcn.h.
Publicado por: 0xDani en 8 Agosto 2012, 11:00 AM
Gracias por la respuesta, pero ya casi lo tengo solucionado, ahora lo unico que me falla es que no linkea con la libreria. Eso si, he desistido de pasarle parametros. Dejo el codigo por si a alguien le sirve, deberia funcionar.

Código (cpp) [Seleccionar]
#include <iostream>
#include <dlfcn.h>

using std::cout;

int main()
{
    typedef void (*function)();
    function result;
    void* handle = dlopen("libprueba-plugin2.so", RTLD_LAZY);
    result = (function)dlsym(handle, "Hello");
    (*result)();
    dlclose(handle);
    return 0;
}


Saludos.

Edit: No puedo compilar este programa, el compilador me lanza 'undefined reference to dlopen()' y lo mismo para las otras funciones de dlfcn.h. He probado a poner -ldl, pero el compilador me da estos errores:
In function `__static_initialization_and_destruction_0(int, int)':
main.cpp:(.text+0x6f): undefined reference to `std::ios_base::Init::Init()'
main.cpp:(.text+0x74): undefined reference to `std::ios_base::Init::~Init()'
collect2: ld devolvió el estado de salida 1
Título: Re: Problema con dlfcn.h.
Publicado por: Eternal Idol en 8 Agosto 2012, 12:16 PM
De nada y ahi arriba tenes como hacerlo con parametros y valor de retorno.

¿Estas usando g++ para compilar?
Título: Re: Problema con dlfcn.h.
Publicado por: 0xDani en 8 Agosto 2012, 12:26 PM
No, estaba usando gcc, pero ahora con g++ ha compilado. Ahora produce violacion de segmento xD.

Saludos.
Título: Re: Problema con dlfcn.h.
Publicado por: Eternal Idol en 8 Agosto 2012, 12:46 PM
Cita de: daniyo en  8 Agosto 2012, 12:26 PM
No, estaba usando gcc, pero ahora con g++ ha compilado. Ahora produce violacion de segmento xD.

Saludos.

Deberias comprobar que dlsym no este devolviendo NULL antes de llamar a result.
Título: Re: Problema con dlfcn.h.
Publicado por: 0xDani en 8 Agosto 2012, 12:57 PM
Ah pues el problema ha resultado estar en dlopen(). dlerror() me dice que no pudo abrir la libreria dinamica. Es raro, porque la tengo en el mismo directorio. Voy a probar a ponerle la ruta completa.

Saludos.

Edit: No la abre ni con la ruta completa.
Edit2: Despues de dlopen(), llamo a dlerror() y me da el error: "libejemplo.so: cannot open shared object file: No such file or directory". He puesto la libreria dinamica en el mismo directorio que el programa, y tambien le he puesto la ruta completa, pero me sigue saltando el mismo error.