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
我不明白我哪里错了......
答案 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
可能无法重入(因此,如果您有多线程应用程序,请将调用序列化为dlopen
和dlsym
使用一些互斥锁。)
答案 1 :(得分:2)
实际上它非常简单,加载器不会查看当前目录。尝试:
./dyna ./libfoo.so
^^^
其他一切看起来都不错。