C++ ODR规则与dlopen 问题
问题:
开发平台*.so插件的时候遇到相同的函数名称出现在不同的.so文件中,假设分别为a.so和b.so,b.so要使用a.so中的定义函数 a(),而在dlopen会先加载a.so然后加载b.so,打开b.so时,会报空指针错误。
基本概念:
ODR在C++标准中被解释为:
1.任何编译单元都不能包含变量、函数、枚举、类或者模板的定义一次以上。
2.所有程序必须且只能包含一次其中用到的所有非内联函数和对象。
3.在需要类的完整定义的编译单元中,类的定义必须且只能出现一次。
4.包括类、枚举、类模板......等等在内的一些定义可以在一个程序中出现多次,但是必须满足以下条件:
(1)所有定义的token序列必须相同(token你可以认为就是有效的语言要素,出了空白、换行注释之类的)
(2)所有的命名查找必须指向同一个实体,也就是说,你不能搞一些命名空间 typedef之类的,让这些相同的token表示不同的意义
(3)所有运算符必须表示同一个重载
(4)对于你要定义的实体中的所有带默认参数的函数,默认参数必须满足以上三条
(5)对于类定义,构造函数中调用的基类构造函数必须是同一个
总而言之,这个第四条的意思就是不同的定义之间不能有任何歧义。
解决方案:
通过分析可知,对于这种情况下跨.so调用函数,需要将函数名称在编译的时候就要对外暴露,不然外部.so会查找不到该函数的定义。
具体方式,在a.so编译中添加a.map文件,其中需要添加要对外暴露的函数。同事需要修改Makefile文件。具体内容如下:
暴露方式为在文在a.map文件中设置Global和Local的函数名称 并通过编译参数指定该内容进行编译:
编译命令:
gcc -Wall -g -fPIC -shared ./a.c -o a.so -Wl,--version-script=a.map
Map文件a.map
{
global:
global_fun_name;
local:*;
};
C++ ODR规则与dlopen 问题的更多相关文章
- STM32 GPIO寄存器 IDR ODR BSRR BRR
IDR是查看引脚电平状态用的寄存器,ODR是引脚电平输出的寄存器 下面内容的原文:http://m646208823.blog.163.com/blog/static/1669029532012931 ...
- 加载动态链接库——dlopen dlsym dlclose
DLOPEN DLMOPEN DLCLOSE NAME dlclose, dlopen, dlmopen - 打开/关闭共享对象 SYNOPSIS #include <dlfcn.h&g ...
- make的使用和Makefile规则和编程及其基本命令(简单)
转自:http://blog.chinaunix.net/uid-23929712-id-2650328.html 概述: make从Makefile中文件中获取模块间的依赖关系,判断哪些文件 ...
- Yii1.1的验证规则
在Yii1.1的数据验证是由CValidator完成,在CValidator中提供了各种基本的验证规则 <?php public static $builtInValidators=array( ...
- iOS之应用版本号的设置规则
版本号的格式:v<主版本号>.<副版本号>.<发布号> 版本号的初始值:v1.0.0 管理规则: 主版本号(Major version) 1. 产品的主体构件进 ...
- ThinkPhp5.0模型验证规则
Tp5提供了模型数据规则的验证功能,用于在数据save或者update前验证数据的有效性.Tp5提供校验规则的类为\Think\Validate,默认提供的校验规则可以查看该文件. 在Model文件中 ...
- PHP 面向对象编程和设计模式 (5/5) - PHP 命名空间的使用及名称解析规则
PHP高级程序设计 学习笔记 2014.06.12 命名空间概述 PHP 在 5.3.0 以后的版本开始支持命名空间.什么是命名空间?从广义上来说,命名空间是一种封装事物的方法.在很多地方都可以见到这 ...
- "Chinese_PRC_CI_AS" 和 "Chinese_PRC_90_CI_AI" 之间的排序规则冲突问题
这个错误真是太恶心了.不过有解决办法,你问我哪来的?当然百度的咯! 示例: select a.workTypeDes from A a,B b where a.workTypeCode=b.work ...
- mysql大小写敏感与校对规则
大家在使用mysql过程中,可能会遇到类似一下的问题: root@chuck 07:42:00>select * from test where c1 like 'ab%'; +-----+ ...
随机推荐
- 简单3d RPG游戏 之 004 攻击(二)
人物和怪物的攻击都有CD冷却,在PlayerAttack脚本中添加成员 //冷却倒计时 public float attackTimer; //CD冷却时间 public float coolDown ...
- NOI2015考试小结
这次NOI2015有幸获得金牌考进了国家集训队,意味着我的OI退役时间既省选之后有延迟了好几个月,又有了新的目标吧. 先说一下考试之外的感受吧,学军宿舍很牛X,接待NOIers而不提供插座,唯一可以用 ...
- 团体程序设计天梯赛-练习集L2-006. 树的遍历
L2-006. 树的遍历 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历 ...
- DIY Ruby CPU 分析——Part III
[编者按]作者 Emil Soman,Rubyist,除此之外竟然同时也是艺术家,吉他手,Garden City RubyConf 组织者.本文是 DIY Ruby CPU Profiling 的第二 ...
- Socat
http://www.oschina.net/p/socat/ tcpick https://sourceforge.net/projects/tcpick/
- IOS开发之表视图(UITableView)
IOS开发之表视图(UITableView)的基本介绍(一) (一):UITableView的基本概念 1.在IOS开发中,表视图的应用十分广泛和普及.因此掌握表视图的用法显得非常重要.一般情况下对于 ...
- linux 2.6 互斥锁的实现-源码分析
http://blog.csdn.net/tq02h2a/article/details/4317211 看了看linux 2.6 kernel的源码,下面结合代码来分析一下在X86体系结构下,互斥锁 ...
- Android 使用split函数进行多个空格分割
在项目中经常会遇到按字符分割字符串的情况,可以使用String对象的split函数进行分割. 先看实际情况: String str = "关键词1 关键词2 关键词3"; Stri ...
- [译]Atomic VS. Non-Atomic 操作
原文链接:atomic-vs-non-atomic-operations 在网上已经写了很多关于原子操作的文章,但是通常都集中在原子的读-修改-写(RMW. read-modify-write)操作. ...
- ActiveMQ之 TCP通讯机制
ActiveMQ支持多种通讯协议TCP/UDP等,我们选取最常用的TCP来分析ActiveMQ的通讯机制.首先我们来明确一个概念: 客户(Client):消息的生产者.消费者对ActiveMQ来说都 ...