2

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

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

4

2 回答 2

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为包含.(不推荐)

PS不要忘记dlerror()用于错误报告,并记住这dlopen可能不是可重入的(因此,如果您有一个多线程应用程序,请序列化对某些互斥体的调用dlopendlsym

于 2013-02-25T07:46:46.257 回答
2

其实很简单,加载器不会在当前目录中查找。尝试:

./dyna ./libfoo.so
       ^^^

其他一切看起来都不错。

于 2013-02-25T07:46:31.437 回答