无法在运行时加载共享库

时间:2013-02-25 07:43:52

标签: c ld dlopen shared-libraries

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");
}

使用

编译
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);
}

编译使用:

gcc -rdynamic -o dyna dyna.c -ldl

运行:

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

我不明白我哪里错了......

2 个答案:

答案 0 :(得分:4)

仔细阅读dlopen(3)手册页。

 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:

所以你应该运行

 ./dyna ./libfoo.so

 ./dyna $PWD/libfoo.so

或者您可以将LD_LIBRARY_PATH设置为包含.(不推荐)

P.S。不要忘记使用dlerror()进行错误报告,并记住dlopen可能无法重入(因此,如果您有多线程应用程序,请将调用序列化为dlopendlsym使用一些互斥锁。)

答案 1 :(得分:2)

实际上它非常简单,加载器不会查看当前目录。尝试:

./dyna ./libfoo.so
       ^^^

其他一切看起来都不错。