首页 > 技术文章 > linux下动态链接库解决方案(一)

zlgxzswjy 2016-03-14 09:22 原文

 1、c++无法直接调用用c写的动态链接库,如果调用的话可能需要用到一些交叉编译的知识;

 

2、在c++写的动态链接库无法被调用成功的反思:

在linux下,通常都是使用g++编译器("g++ -shared -fPIC -lc -o xxx xxx.cpp")来进行编译,直接对写好的函数这样编译通常都会报错,因为c++支持函数重载,导致了一些命名规则在g++编译器中无法通过,这个时候,通常我们会选择继续使用c编译器来进行编译,这里就要用到一个extern "C"这样的标识符来限定这部分函数使用c编译器来编译。

我这里举个简单的例子:

库文件中有一个求和函数和一个求差函数:

//libsth.cpp
/*这是库文件libsth.so的源代码*/
1
#include<iostream> 2 using namespace std; 3 extern "C" 4 { 5 int add(int a,int b) 6 { 7 return a+b; 8 } 9 int sub(int a,int b) 10 { 11 cout<<"this is a test"<<endl; 12 return a-b; 13 } 14 15 }
//编译命令:g++ -shared -lc -fPIC -o libsth.so libsth.cpp

加这个external  “C”很重要,因为dlsym的默认返回值是"void *",而这里的函数返回值是int,如果是c编译器,这没有问题,会直接通过。

我的建议是,把返回值为非“void *”的函数都写在external "C"框架下,这样可以减少很多麻烦,通用性也好

下面是main()函数的具体实现代码:

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<dlfcn.h>
 4 #include<iostream>
 5 using namespace std;
 6 typedef int (*add_t)(int,int);
 7 typedef int (*sub_t)(int,int);
 8 int main()
 9 {
10                 int a,b;
11                 void *handle;
12                 //int (*add)(int,int);
13                 add_t add;
14                 sub_t sub;
15                 if((handle=dlopen("./libsth.so",RTLD_LAZY))==NULL)//打开我们生成的动态链接库文件
16                 {
17                                 cout<<"open lib error!"<<endl;
18                                 exit(0);
19                 }
20                 if((add=(add_t)dlsym(handle,"add"))==NULL)//找到"add"函数在动态链接库的地址
21                 {
22                                 cout<<"get address add error!"<<endl;
23                                 exit(0);
24                 }
25                 if((sub=(sub_t)dlsym(handle,"sub"))==NULL)//找到"add"函数在动态链接库的地址,注意这里的"add"指的是动态链接库中的add函数,注意与下面的区分
26                 {
27                                 cout<<"get address sub error!"<<endl;
28                                 exit(0);
29                 }
30                 a=add(1,2);//调用库函数,注意这里的“add”指的是变量定义“add_t add;”中的代码
31                 b=sub(1,2);//同上
32                 cout<<a<<endl;
33                 cout<<b<<endl;
34                 dlclose(handle);
35                 return 0;
36 }
//编译命令:g++ -ldl -o libm libmain.cpp

这样,一个动态链接库及其调用模型就建立起来了

学习之前也从网上看了好多资料,确实讲的很专业,但对于初学者来说,许多专业名词都无法理解,故此写下一点直观的调用方法,仅供参考,

感谢来自百度文库一片文章的启发:http://wenku.baidu.com/link?url=RSss_gbiYTkCSJDA07MB9s1tyVyPlRZTeYSVHxjkQ9EjCHW118T8TkMOr02NLLaoUowLVjBDNmvkhAGAXG1YUVpYqJDFb65M9M3wNYCTyQi

 

推荐阅读