操作系统Centos 5.6 i686 2.6.18-53.1.4.el5vm.

gcc版本4.1.2 20080704(Red Hat 4.1.2-48)

ld版本2.17.50.0.6-6.el5 20061020

我以这种方式编译:

gcc -c -fnon-call-exceptions -fexceptions -Wall -DUNICODE -D_UNICODE -D_REENTRANT -I.

并以这种方式链接:

gcc -lstdc -pthread -ldl -lrt –no-relocate -Wl,-rpath,$SO_DIR -L $SO_DIR $LIBRARIES

我有3个库和一个可执行文件:A.so,B.so,C.so,ElfExec

B.so取决于A.so.

C.so取决于B.so.

在代码A.so中具有通过其公开功能A.h的标头,在代码中B.so具有B.h标头,其中包括A.h和B的功能.代码中的C.so包括B.h.

A.h定义了一个静态变量K,该类型可以在且仅当初始化A.so的静态内存管理器时使用.变量K在头文件A.h中直接定义,因此,它的初始化在组成B.so和C.so的所有对象的全局构造函数中传播.

我像这样链接所有内容:

gcc“所有B模块” -lstdc -pthread -ldl -lrt –no-relocate -Wl,-rpath,$SO_DIR -L $SO_DIR A.so

gcc“所有C模块” -lstdc -pthread -ldl -lrt-无重定位-Wl,-rpath,$SO_DIR -L $SO_DIR B.so

gcc“所有ElfExec模块” -lstdc -pthread -ldl -lrt –no-relocate -Wl,-rpath,$SO_DIR -L $SO_DIR C.so

我也尝试过:

gcc“所有ElfExec模块” -lstdc -pthread -ldl -lrt –no-relocate -Wl,-rpath,$SO_DIR -L $SO_DIR A.so B.so C.so

ElfExec在运行时会收到SIGSEGV,因为它会在初始化A.so的静态内存管理器之前尝试初始化变量K.

这是因为C.so的全局构造函数在A.so的全局构造函数之前被调用.

如果我制作只需要B.so的应用程序ElfExec2

gcc“所有ElfExec1模块” -lstdc -pthread -ldl -lrt –no-relocate -Wl,-rpath,$SO_DIR -L $SO_DIR B.so

这正常工作.

对于ElfExec1,链接器看到需要先调用A.so中的全局构造函数,然后再调用B.so中的全局构造函数.

在ElfExec的情况下,这不会受到限制.

我的解决方案是这样链接C.so:

gcc“所有C模块” -lstdc -pthread -ldl -lrt –no-relocate -Wl,-rpath,$SO_DIR -L $SO_DIR A.so B.so

这使C.so与A.so直接相关.

还有另一种方式可以告诉链接程序全局构造函数调用的顺序吗?

解决方法:

如您所见,不要相信链接器比您更了解.如果顺序很重要,则需要以编程方式指定顺序.不要只是试图欺骗链接器.

如果这些不是库,那就是您要做的,对吧?以正确的顺序互相调用的构造函数/初始化函数?

我的第一选择是将库设计为不具有或使用全局变量.

如果您不能这样做,那么我的第二个选择是为每个需要初始化全局变量以具有init方法的库.库的使用者需要先调用该init方法,然后才能执行任何操作,并且库必须尝试阻止使用/构造,直到正确完成init为止.也许将它们静态化为init方法,然后设置指向它们的全局指针(K * k)可能有助于实现.这应该足以使初始化链以正确的顺序组合在一起.

最后,如果让任何库的用户(对于A表示B,对于C表示B,对于C而言,C)的用户都遇到障碍,则可以对gcc使用如下语言扩展:

extern "C" __attribute__ ((constructor)) void A_lib_ctor()

{

// ....

}

extern "C" __attribute__ ((destructor)) void A_lib_dtor()

{

// ....

}

在加载库时自动执行所需的操作.这牺牲了一些可移植性.可能会牺牲更多,较新版本的gcc支持构造函数(优先级)语法.

我的最后选择是使用dlopen手动加载库的复杂步骤.

对于您而言,最重要的选择是设计更好,而后来的选择则更糟.

标签:gcc,linker,ld,linux

来源: https://codeday.me/bug/20191102/1991358.html

linux 动态库构造函数,Linux共享库全局构造函数的相互依赖性相关推荐

  1. Linux下开源库的使用(共享库文件头文件配置全局搜索)(WSL)

    关键词 g++; vscode; c++; pkg-config; include; lib; linux; .pc; tasks.json; launch.json; WSL 前言 需求及手动解决方 ...

  2. linux ubuntu dlopen,linux – 使用dlopen()加载共享库时出错

    我正在开发一个程序,在CentOS上使用dlopen加载用户创建的插件.我遇到了一个插件的问题,该插件依赖于也具有依赖关系的共享库: libplugin.so – > libservices.s ...

  3. linux g++ 链接,Linux G++将64位共享库代码链接到静态库

    如果对象模块将在共享库中使用,则始终需要"位置独立代码".它高度依赖于平台,并且会产生一些开销. 您必须在amd64而不是x386上显式指定它的原因只是它恰好是x86的默认值,而不 ...

  4. linux如何进入解释器路径,如何更改解释器路径并将命令行参数传递给Linux上的可执行共享库?...

    以下是"可执行"共享库的最小示例(假定文件名:)mini.c: // Interpreter path is different on some systems //+defini ...

  5. 动态库.so(共享库)的制作和使用

    动态库的制作 1.首先建立三个C文件以及相应的头文件 2. 现将.c文件编译成.o文件 gcc -fpic -c test1.c test2.c 3.将第2步编译的.o文件生成动态库 gcc -sha ...

  6. linux 动态连接原理,Linux动态连接原理 GOT PLT表详解

    注意: 以下所用的连接器是指,ld, 而加载器是指ld-linux.so; 1,GOT表: GOT(Global Offset Table)表中每一项都是本运行模块要引用的一个全局变量或函数的地址.可 ...

  7. linux 动态执行cp,Linux常用命令之cp、mv、rm、cat、more、head、tail、ln命令讲解

    上一章节中,我们了解到了Linux系统的最基础的几个文件处理命令,核心的是ls命令,在今天这章中,我们来继续学习Linux对于文件操作相关的一些命令,比如复制.移动.删除.查看等命令. 1.cp 命令 ...

  8. linux 动态增加inode,linux 增加inode 的方法

    创建文件系统时,可以指定块的大小.如果将来在你的文件系统中是一些比较大的文件的话,使用较大的块大小将得到较好的性能.将ext2文件系统的块大小调整为4096byte而不是缺省的1024byte,可以减 ...

  9. Linux动态加载共享库,Linux共享库的动态加载(附测试案例)

    共享库的动态加载是指可以在程序运行的过程中去加载所需的共享库.常用于某些系统或者应用程序的自动升级. 在C语言的源程序动态加载共享库,需要调用一组特殊的函数,它们被声明于一个专门的头文件dlfcn.h ...

  10. Linux平台gcc和动态共享库的基础知识

    http://www.javaeye.com/topic/261176 对大多数不从事Linux平台C语言开发的人来说,GNU gcc的一套工具和Linux平台的共享库的使用还是十分陌生的,其实我也不 ...

最新文章

  1. 两度延期,K项目终于要开工了!
  2. c#_continue 和 break 的区别
  3. UNIX/LINUX程序设计教程(1)-- 获取系统信息
  4. springboot nacos配置中心_SpringBoot开发案例之Nacos配置管理中心
  5. html辅助方法实现原理,前端每日实战:苦练 CSS 基本功——图解辅助线的原理和画法...
  6. java 友好变量单词_“友好”的英语单词是什么?
  7. ZYNQ图像处理(2)——ov5640_hdmi显示环境搭建
  8. 深度解读,北斗与综合PNT体系
  9. Hadoop上路-03_Hadoop JavaAPI
  10. 攻防世界Web新手区题解
  11. T-Code (Controlling)
  12. 涉密计算机不得接入互联网等公共信息网络,在涉密场所使用的与国际互联网或者其他公共网络连接的计算机不得安装视频、音频等输入装置 - 作业在线问答...
  13. 2022泰迪杯数据分析技能赛B题方案及赛后总结:银行客户忠诚度分析
  14. echarts世界地图
  15. 基于脑机接口的人脑控制机械手臂
  16. 排名 oracle,Oracle基本查询查看排名
  17. 2017中国国际教育装备博览会会刊(参展商名录)
  18. 2、Arduino开发语言
  19. 塑化行业SRM供应商管理系统:缩短采购周期时间,改善供应商采购管理
  20. 湖大计算机人工智能专业导师,湖南大学人工智能专业

热门文章

  1. 浅谈 OneAPM 在 express 项目中的实践
  2. opencv 绘制坐标曲线_OpenCV手工实现灰度及RGB直方图
  3. Java Short类hashCode()方法及示例
  4. ruby array_Ruby中带有示例的Array.fill()方法(1)
  5. Java Double类hashCode()方法及示例
  6. ICWAI和ICWA的完整形式是什么?
  7. c++ scanf读取_使用scanf()读取内存地址并在C中打印其值
  8. 内蒙古师范大学计算机科学技术学院,内蒙古师范大学计算机科学技术硕士生导师——李成城...
  9. mysql 线性表_数据结构之线性表
  10. sdr 软件_【火腿专题】购买软件定义无线电(SDR)还是传统无线电台?追求欲望无止境...