在Windows中加载共享库时,LoadLibrary()调用库中的原因DllMain,以便为每个新进程和线程库附加,以及为每个进程和线程库执行detaaches.
Mac OS X,Linux和其他POSIX兼容的操作系统是否有类似的机制?
我正在Linux下使用C++开发一个共享库,我希望这个库使用log4cxx进行日志记录.但是,我不知道如何设置它.要使log4cxx工作,我需要创建一个logger对象.如何在加载库时确保创建此对象?
我怀疑最简单的方法是将logger对象创建为全局变量,然后在我的库的任何源文件中使用它,并在标题中将其声明为extern.但是,如果应用程序连接到库,我怎样才能自动创建记录器?
我知道在Windows的DLL中,有一个东西是REASON_FOR_CALL == PROCESS_ATTACH; Linux下有类似的东西吗?
这里的答案表明,静态初始化后不调用__attribute __((构造函数)),它在声明顺序中调用.
那么,如果在初始化所有数据时不能保证调用它的目的是什么呢?我们也可以在Foo构造函数中使用我们的((构造函数)代码.
我正在寻找的是一种在共享库中拥有一个代码的方法,该代码将在初始化所有静态数据并调用静态构造函数之后执行.我看到人们推荐__attribute __((构造函数))作为DllMain的替代品; 我们可以看到这是错误的,因为某些静态数据可能仍未初始化.
当然在单个文件(编译单元)中我们可以安排静态.但在典型的程序中有很多文件.在初始化共享库中的所有其他静态之后,有没有办法保证一个文件中的((构造函数))肯定会被调用?
如果我将一个带有静态初始化(构造函数,对象等)的文件放到gcc命令行的末尾:
g++ -shared -fPIC source1.o source2.o MyLastInitChance.o
Run Code Online (Sandbox Code Playgroud)
这个文件的静态构造函数是否保证最后被调用?我试验过,当我改变源文件的顺序时,printfs的顺序改变了; 但它是否在某处指定并保证在编译系统/计算机上相同?
例如,引用:
在链接时,gcc驱动程序在所有可重定位文件之前立即放置crtbegin.o,在所有可重定位文件之后立即放置crtend.o.©
根据我的理解,上面的引用暗示传递给链接器的.o文件的顺序定义了静态初始化的顺序.我对么?
另一个有趣的解决方案可能是编写一个GCC插件来调整静态初始化(例如将代码添加到.ctors部分等).但这只是一个可能有人可以扩展的想法.
这里介绍了另一种可能的解决方案.简而言之,可以使用外部构建后工具来重新排序可执行文件(库)中的.ctors条目.但我不是ELF格式的专家; 我想知道这是否可行且容易以这种方式调整.so文件.
我感兴趣的是解决一个特定的问题,或证明它是不可能解决的(至少为什么上面的解决方案不起作用).
我一直在寻找一种方法来建立一个共享库(让我们命名库libbar.so)延迟加载到Linux上,它应该只在一个链接器的帮助下实现,而不是修改用C++编写的源代码的任何东西; 我的意思是我不想要调用dlopen(),也没有dlsym()在母库的源代码(我们将其命名为libfoo.so)调用的函数libbar.so,因为它们使源代码混乱和维护过程困难.(简而言之,/DELAYLOAD即使在Linux 上,我也期望以类似的方式使用Visual Studio的选项)
无论如何,到目前为止,我已经在互联网上找到了与我的问题相关的一些不确定的信息片段,所以很高兴能得到你们所有人的答案,以便让信息清晰.
dlopen()家庭,使装在Linux上的共享库延迟的唯一途径?我测试了将-zlazy标志传递给GCC(g ++)并带有一个到库的路径,它似乎接受了标志,但是行为看起来没有libbar.so加载延迟(没有libbar.so,我期待在第一次调用时有异常libbar.so,但是在进入之前实际提出的例外libfoo.so).另一方面,Clang(clang++)发出警告,忽略了选项标志.
最好的祝福,