问题

开发平台*.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 问题的更多相关文章

  1. STM32 GPIO寄存器 IDR ODR BSRR BRR

    IDR是查看引脚电平状态用的寄存器,ODR是引脚电平输出的寄存器 下面内容的原文:http://m646208823.blog.163.com/blog/static/1669029532012931 ...

  2. 加载动态链接库——dlopen dlsym dlclose

    DLOPEN DLMOPEN DLCLOSE NAME     dlclose, dlopen, dlmopen - 打开/关闭共享对象 SYNOPSIS #include <dlfcn.h&g ...

  3. make的使用和Makefile规则和编程及其基本命令(简单)

      转自:http://blog.chinaunix.net/uid-23929712-id-2650328.html   概述: make从Makefile中文件中获取模块间的依赖关系,判断哪些文件 ...

  4. Yii1.1的验证规则

    在Yii1.1的数据验证是由CValidator完成,在CValidator中提供了各种基本的验证规则 <?php public static $builtInValidators=array( ...

  5. iOS之应用版本号的设置规则

    版本号的格式:v<主版本号>.<副版本号>.<发布号>  版本号的初始值:v1.0.0 管理规则: 主版本号(Major version) 1.  产品的主体构件进 ...

  6. ThinkPhp5.0模型验证规则

    Tp5提供了模型数据规则的验证功能,用于在数据save或者update前验证数据的有效性.Tp5提供校验规则的类为\Think\Validate,默认提供的校验规则可以查看该文件. 在Model文件中 ...

  7. PHP 面向对象编程和设计模式 (5/5) - PHP 命名空间的使用及名称解析规则

    PHP高级程序设计 学习笔记 2014.06.12 命名空间概述 PHP 在 5.3.0 以后的版本开始支持命名空间.什么是命名空间?从广义上来说,命名空间是一种封装事物的方法.在很多地方都可以见到这 ...

  8. "Chinese_PRC_CI_AS" 和 "Chinese_PRC_90_CI_AI" 之间的排序规则冲突问题

    这个错误真是太恶心了.不过有解决办法,你问我哪来的?当然百度的咯! 示例: select a.workTypeDes from A a,B b  where a.workTypeCode=b.work ...

  9. mysql大小写敏感与校对规则

    大家在使用mysql过程中,可能会遇到类似一下的问题: root@chuck 07:42:00>select * from test where c1 like 'ab%';  +-----+  ...

随机推荐

  1. linux上很方便的上传下载文件工具rz和sz

    linux上很方便的上传下载文件工具rz和sz(本文适合linux入门的朋友) ##########################################################&l ...

  2. .substr()在字符串每个字母前面加上一个1

    var str = "abcdefghijklmnopq", name = "1", ary = []; for(var i = 0,len = str.len ...

  3. [转载].Net中如何操作IIS(源代码)

    ///***********************************************************///************** IIS控制管理类 1.0 Beta ** ...

  4. 改善用户体验之wordpress添加图片弹出层效果 (插件 FancyBox)

    下面说说在改善用户体验之wordpress添加图片弹出层效果.效果图如下:   像这篇文章如何在百度搜索结果中显示网站站点logo? 文章内有添加图片,没加插件之前用户点击图片时,是直接_black打 ...

  5. Tiny6410 设备驱动之helloworld

    在自己的工作目录下建立helloworld_driver.c #include <linux/init.h> #include <linux/module.h> //代码遵守的 ...

  6. Topo图

    http://blog.csdn.net/youfangyuan/article/details/8367398 http://joshuaxiao.iteye.com/blog/2224120 ht ...

  7. 【形式化方法:VDM++系列】2.VDMTools环境的搭建

    接前文:http://www.cnblogs.com/Kassadin/p/3975853.html 上次讲了软件需求分析的演化过程,本次进入正题——VDM开发环境的搭建 (自从发现能打游戏以来,居然 ...

  8. hibernate 数据行数统计 count(*)

    Hibernate关于sql中的count(*)数据统计: ①如果使用的是HQL: 直接在HQL中使用count(*)即可获取行数 Long count = (Long)HibernateUtil.g ...

  9. APP,webapp 设计相关资料汇集区

    (1).@2x iPhone3GS时代,我们为一个应用提供图标(或按钮提供贴图),只需要icon.png.针对现在的iPhone4~6 Retina显示屏,需要制作额外的@2x高分辨率版本. 例如在i ...

  10. android应用崩溃的调试方法(c++ lib so文件库崩溃)

    android调试工具addr2line使用: 1.将ndk中的arm-linux-androideabi-addr2line可执行文件的路径加入配置文件~/.bashrc中,例如: export P ...