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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值