linux下动态链接库解决方案(一)

时间:2022-10-09 19:35:32

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>
using namespace std;
extern "C"
{
int add(int a,int b)
{
return a+b;
}
int sub(int a,int b)
{
cout<<"this is a test"<<endl;
return a-b;
} }
//编译命令:g++ -shared -lc -fPIC -o libsth.so libsth.cpp

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

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

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

 #include<cstdio>
#include<cstdlib>
#include<dlfcn.h>
#include<iostream>
using namespace std;
typedef int (*add_t)(int,int);
typedef int (*sub_t)(int,int);
int main()
{
int a,b;
void *handle;
//int (*add)(int,int);
add_t add;
sub_t sub;
if((handle=dlopen("./libsth.so",RTLD_LAZY))==NULL)//打开我们生成的动态链接库文件
{
cout<<"open lib error!"<<endl;
exit();
}
if((add=(add_t)dlsym(handle,"add"))==NULL)//找到"add"函数在动态链接库的地址
{
cout<<"get address add error!"<<endl;
exit();
}
if((sub=(sub_t)dlsym(handle,"sub"))==NULL)//找到"add"函数在动态链接库的地址,注意这里的"add"指的是动态链接库中的add函数,注意与下面的区分
{
cout<<"get address sub error!"<<endl;
exit();
}
a=add(,);//调用库函数,注意这里的“add”指的是变量定义“add_t add;”中的代码
b=sub(,);//同上
cout<<a<<endl;
cout<<b<<endl;
dlclose(handle);
return ;
}
//编译命令:g++ -ldl -o libm libmain.cpp

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

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

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