linux下动态链接库解决方案(一)
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
linux下动态链接库解决方案(一)的更多相关文章
- linux下动态链接库解决方案(二)
以前写过一个关于linux下用c++写动态链接库无法通过的解决方案,今天看到<linux C程序设计-王者归来>这本书,书中有个更容易的解决方案,特此记录下来 书中使用的是c语言,我改用c ...
- linux下动态链接库.so文件 静态链接库.a文件创建及使用
转摘网址为:http://www.cnblogs.com/fengyv/archive/2012/08/10/2631313.html Linux下文件的类型是不依赖于其后缀名的,但一般来讲: ...
- Linux下动态链接库和静态链接库
第一部分:编译过程 先了解一下linux下C代码的编译过程,C代码的编译,一般分成四个阶段,包括:预编译,编译,汇编和链接,这四个阶段的分工是 预处理过程,负责头文件展开,宏替换,条件编译的选择,删除 ...
- linux下动态链接库(.so)的显式调用和隐式调用
进入主题前,先看看两点预备知识. 一.显式调用和隐式调用的区别 我们知道,动态库相比静态库的区别是:静态库是编译时就加载到可执行文件中的,而动态库是在程序运行时完成加载的,所以使用动态库的程序的体积要 ...
- LINUX下动态链接库的使用-dlopen dlsym dlclose dlerror(转)
dlopen 基本定义 功能:打开一个动态链接库 包含头文件: #include <dlfcn.h> 函数定义: void * dlopen( const char * pathn ...
- LINUX下动态链接库的使用-dlopen dlsym dlclose dlerror
本定义 功能:打开一个动态链接库 包含头文件: #include <dlfcn.h> 函数定义: void * dlopen( const char * pathname, int mod ...
- Linux下动态链接库 与gcc 选项
-L 编译时查找动态链接库的路径 -lxxx(小写) e.g -lcudart = link libcudart.so , -I(大写) 头文件的路径 -rpath (-R), 编译时指定链接 ...
- Linux下动态链接库加载路径
引子 近日,服务器迁移后,偷懒未重新编译nginx的,直接./nginx启动,结果遇到如下问题: "error while loading shared libraries" 这是 ...
- LINUX下动态库及版本号控制
针对同一动态组件的不同版本链接和加载. 一.概念 DLL HELL字面意思是DLL"灾难",是由于com组件(动态库)升级引起的程序不能运行的情况 ...
随机推荐
- 【CISP笔记】操作系统安全
账号安全设置 默认管理账号Administrator更名,设置密码(字母.数字.大小写字母.特殊字符,长度在8位以上). 本地安全策略 打开方式 win+R 输入ecpol.msc 账号锁定策略 用户 ...
- gdb调试core文件
本人最近正在学习调试技术,此处对栈溢出做一些总结. gdb的基本使用就不多扯了. 主要针对发行在外的release版本的软件出现问题时的调试. 一般来讲,查看堆栈就是使用bt,这个时候加上bt ful ...
- getRow()方法
getRow :不是返回行数,而是返回当前是哪一行
- Lexicography(数学推论>>求按字典序排第k个排列)
Lexicography Time Limit:1000MS Memory Limit:131072KB 64bit IO Format:%lld & %llu Submit ...
- 如何编译Apache Hadoop2.6.0源代码
如何编译Apache Hadoop2.6.0源代码 1.安装CentOS 我使用的是CentOS6.5,下载地址是http://mirror.neu.edu.cn/centos/6.5/isos/x8 ...
- phpcms中常用代码总结
1.调用数据库模型 $this->db = pc_base::load_model('test_model');//从"phpcms/model/"目录下加载模型类文件 其中 ...
- iOS开发——高级篇——换肤、静态库
一.换肤 1.思路1> 解决方案1,使用颜色作为图片素材的命名关键字 问题1:要保证每套图片的文件名 颜色+ 名称.png的格式比较麻烦 问题2:如果要将某一个图片应用到其他皮肤不方便2> ...
- UOJ52——【UR #4】元旦激光炮
1.题目大意:就是给你三个数组啦,然后让你找到其中的第K大,但是,不可以直接访问数组,必须通过一种函数,最后的分数 是看调用几次这个函数,100次以内10分,2000以内6分.... 2.分析:最开始 ...
- h5上传图片
1.如何在H5上传图片 使用FileReader 2.FileReader接口 传图片我们只用到readAsDataURL 3.FileReader接口事件 传图片我们只用到onload 4.如何使用 ...
- 取数据的前N行
用awk中csv文件中取前1000行出来,代码虽少,很容易出错 BEGIN{ FS=","; OFS=","; i=; } { i++; )exit; prin ...