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