Pregunta

foo.h

#ifndef foo_h__
#define foo_h__ 
extern void foo(void); 
#endif

foo.c

#include <stdio.h>
#include "foo.h" 
void foo(void)
{
    puts("Hello, I'm a shared library");
}

compiled using

gcc -Wall -fPIC -c foo.c
gcc -shared -Wl,-soname,libfoo.so -o libfoo.so foo.o

dyna.c

#include <stdio.h>
#include <unistd.h>
#include <dlfcn.h> 
typedef void (*foo)(void);
int main(int argc, char* argv[])
{
    void* lib;
    foo df;
    printf("argc: %d\n",argc);
    if(argc < 2)
        return printf("USAGE: %s lib-file\n", argv[0]);

    lib = dlopen(argv[1], RTLD_NOW);
    if(lib == NULL)
        return printf("ERROR: Cannot load library\n");

    df = dlsym(lib, "foo");
    if(df)
    {
    df();
    }
    else
        printf("ERROR: Invalid library\n");
    dlclose(lib);
}

compiled using:

gcc -rdynamic -o dyna dyna.c -ldl

run:

./dyna libfoo.so
argc: 2
ERROR: Cannot load library

I do not understand where am I going wrong...

¿Fue útil?

Solución

Read carefully the dlopen(3) man page.

 If filename contains a slash ("/"), then it is interpreted as a
 (relative or absolute) pathname.  Otherwise, the dynamic linker 
 searches for the library as follows:

So you should run

 ./dyna ./libfoo.so

or

 ./dyna $PWD/libfoo.so

or you could set LD_LIBRARY_PATH to contain . (which is not recommended)

P.S. don't forget to use dlerror() for error reporting, and remember that dlopen is probably not re-entrant (so if you have a multi-threaded application, serialize the calls to dlopen and dlsym with some mutex).

Otros consejos

It's really simple actually, the loader doesn't look in the current directory. Try:

./dyna ./libfoo.so
       ^^^

Everything else looks good.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top