dlopen调用动态库运行出现undefined symbol
1. 库源码
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int add(int a,int b)
{
return (a + b);
}
int sub(int a, int b)
{
return (a - b);
}
int mul(int a, int b)
{
return (a * b);
}
int div1(int a, int b)
{
return (a / b);
}
2. 将库源码命名为DyncAppLib.cpp,用g++编译
g++ -fPIC -shared DyncAppLib.cpp -o libDync.so
通过nm工具看动态库函数列表
root@0ca8a8fd81e8:/data/# nm -D libDync.so
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
w _Jv_RegisterClasses
00000000000006f0 T _Z3addii
0000000000000716 T _Z3mulii
0000000000000704 T _Z3subii
0000000000000729 T _Z4div1ii
0000000000200aa8 B __bss_start
w __cxa_finalize
w __gmon_start__
0000000000200aa8 D _edata
0000000000200ab0 B _end
000000000000073c T _fini
00000000000005a0 T _init
3. 将库源码命名为DyncAppLib.c,用gcc编译
gcc -fPIC -shared DyncAppLib.c -o libDync.so
root@0ca8a8fd81e8:/data# nm -D libDync.so
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
w _Jv_RegisterClasses
0000000000200a48 B __bss_start
w __cxa_finalize
w __gmon_start__
0000000000200a48 D _edata
0000000000200a50 B _end
000000000000070c T _fini
0000000000000568 T _init
00000000000006c0 T add
00000000000006f9 T div1
00000000000006e6 T mul
00000000000006d4 T sub
4. 主函数命名为DyncAppTest.c源码
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
//动态链接库路径
#define LIB_CACULATE_PATH "./libDync.so"
//函数指针
typedef int (*CAC_FUNC)(int, int);
int main()
{
void *handle;
char *error;
CAC_FUNC cac_func = NULL;
//打开动态链接库
handle = dlopen(LIB_CACULATE_PATH, RTLD_LAZY);
if (!handle) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
//清除之前存在的错误
dlerror();
//获取一个函数
*(void **) (&cac_func) = dlsym(handle, "add");
if ((error = dlerror()) != NULL) {
fprintf(stderr, "%s\n", error);
exit(EXIT_FAILURE);
}
printf("add: %d\n", (*cac_func)(2,7));
cac_func = (CAC_FUNC)dlsym(handle, "sub");
printf("sub: %d\n", cac_func(9,2));
cac_func = (CAC_FUNC)dlsym(handle, "mul");
printf("mul: %d\n", cac_func(3,2));
cac_func = (CAC_FUNC)dlsym(handle, "div1");
printf("div: %d\n", cac_func(8,2));
//关闭动态链接库
dlclose(handle);
exit(EXIT_SUCCESS);
}
5. 主函数g++编译、运行
root@0ca8a8fd81e8:/data# g++ -rdynamic -o DyncApp DyncAppTest.cpp -ldl
root@0ca8a8fd81e8:/data# ./DyncApp
./libDync.so: undefined symbol: add
6. 主函数gcc编译、运行
root@0ca8a8fd81e8:/data# gcc -o DyncAppTest DyncAppTest.c -ldl
root@0ca8a8fd81e8:/data# ./DyncAppTest
7. 从上面分析,c++编译成动态库后其接口无法被访问,需要修改,这里用到extern "C",修改后的库源码DyncAppLib.cpp为
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
extern "C"{
int add(int a,int b)
{
return (a + b);
}
int sub(int a, int b)
{
return (a - b);
}
int mul(int a, int b)
{
return (a * b);
}
int div1(int a, int b)
{
return (a / b);
}
}
root@0ca8a8fd81e8:/data# g++ -fPIC -shared DyncAppLib.cpp -o libDync.so
root@0ca8a8fd81e8:/data# ./DyncAppTest
add: 9
sub: 7
mul: 6
div: 4
版权声明
本文仅代表作者观点,不代表博信信息网立场。
上一篇:三(二)、AOP配置 下一篇:CSS篇二