参考http://blog.chinaunix.net/uid-20801390-id-3157134.html
首先是动态调用动态库
test_so1.h和test_so1.cpp生成test_so1.so动态库。
test_so2.h和test_so2.cpp生成test_so2.so动态库。
test_dll.cpp生成test_dll可执行程序,test_dl通过dlopen系列等API函数,并使用函数指针以到达动态调用不同so库中test函数的目的。
////////////////////////////////test_so1.h//////////////////////////////////////////////////////
#include<iostream>
extern "C" {
int test(void);
}
////////////////////////////////test_so1.cpp//////////////////////////////////////////////////////
#include "test_so1.h"
int test(void)
{
cout<<"USING TEST_SO1.SO NOW!\n"<<endl;//注意此处与test_so2.cpp中的
//test函数的不同
return 0;
}
//////////////////////////////// test_so2.h //////////////////////////////////////////////////////
#include<iostream>
extern "C" {
int test(void);
}
////////////////////////////////test_so2.cpp//////////////////////////////////////////////////////
#include "test_so2.h"
int test(void)
{
cout<<"USING TEST_SO2.SO NOW!\n"<<endl;//注意此处与test_so1.cpp中的
//test函数的不同
return 0;
}
////////////////////////////////test_dll.cpp//////////////////////////////////////////////////////
#include<iostream>
#include<dlfcn.h>
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char **argv)
{
if(argc!=2)
{
cout<<"Argument Error! You must enter like this:"<<endl;
cout<<"./test_dl test_so1.so"endl;
exit(1);
}
void *handle;
char *error;
typedef void (*pf_t)(); //声明函数指针类型
handle = dlopen (argv[1], RTLD_NOW); //打开argv[1]指定的动态库
if (!handle)
{
fprintf (stderr, "%s\n", dlerror());
exit(1);
}
dlerror();
pf_t pf=(pf_t)dlsym(handle,"test" ); //指针pf指向test在当前内存中的地址
if ((error = dlerror()) != NULL)
{
fprintf (stderr, "%s\n", error);
exit(1);
}
pf(); //通过指针pf的调用来调用动态库中的test函数
dlclose(handle); //关闭调用动态库句柄
return 0;
}
//然后下面是参考的文章中的Makefile
////////////////////////////////makefile//////////////////////////////////////////////////////
.SUFFIXES: .c .cpp .o
CC=g++ -shared -fPIC
GCC=g++
all:test_so1.so test_so2.so test_dll clean
OBJ1=test_so1.o
OBJ2=test_so2.o
OBJ3=test_dll.o
test_so1.so:$(OBJ1)
$(CC) -o $@ $?
cp $@ /usr/lib
test_so2.so:$(OBJ2)
$(CC) -o $@ $?
cp $@ /usr/lib
test_dll:$(OBJ3)
$(GCC) -o $@ $? -ldl
.cpp.o:
$(CC) -c $*.cpp
.c.o:
$(CC) -c $*.c
clean:
rm -f *.o
在终端中的当前指令下执行make是,生成了test_so1.so和test_so2.so的动态库文件,但是还会出现下面的错误。
huangbo@huangbo:~/test4$ sudo make
g++ -shared -fPIC -c test_so2.cpp
g++ -shared -fPIC -o test_so2.so test_so2.o
cp test_so2.so /usr/lib
g++ test_dll.cpp -o test_dll
/tmp/cc1ywB9U.o:在函数‘main’中:
test_dll.cpp:(.text+0x6b):对‘dlopen’未定义的引用
test_dll.cpp:(.text+0x7b):对‘dlerror’未定义的引用
test_dll.cpp:(.text+0xa6):对‘dlerror’未定义的引用
test_dll.cpp:(.text+0xb7):对‘dlsym’未定义的引用
test_dll.cpp:(.text+0xc0):对‘dlerror’未定义的引用
test_dll.cpp:(.text+0x109):对‘dlclose’未定义的引用
collect2: error: ld returned 1 exit status
make: *** [test_dll] 错误 1
由于自己是菜鸟,还不知道是什么原因引起的。经查资料发现。如果执行
huangbo@huangbo:~/test4$ g++ test_dll.cpp -ldl -o test_dll
则可以生成test_dll的动态库。
然后则可以正常运行
huangbo@huangbo:~/test4$ ./test_dll test_so1.so
USING TEST_SO1.SO NOW!
huangbo@huangbo:~/test4$ ./test_dll test_so2.so
USING TEST_SO2.SO NOW!
huangbo@huangbo:~/test4$ ./test_dll
Argument Error! You must enter like this:
./test_dl test_so1.so
参考的文章是http://www.linuxdiyf.com/linux/16754.html。原因可以看这篇文章 ////////ps:上面的Makefile可以正常生成可执行文件,是我弄错了导致出现问题!!