dlopen'ing 时静态初始化(and/or 其他)代码是否得到 运行?

Does static initialization (and/or other) code get run when dlopen'ing?

当您 dlopen() 一个共享对象时,是否有一种机制可以让该 DLL 中的代码在不显式调用的情况下执行?具体来说,dlopen() 的调用者可能不知道的 globals/statics 的 C++ 静态初始化代码?我很确定答案应该是 "yes",但我不记得是什么机制使它发生,以及如何将它用于 运行 任意代码。

是:dlopen 在加载时尊重 运行ning 代码的 ELF 二进制格式机制。

实际上有两种这样的机制:

  • 旧的使用特殊的 .init.finis 部分,其中包含一组函数指针供 dlopendlclose 调用。由于这些部分可能不会在 运行 时间出现,因此还有 DT_INITDT_FINI 指向相应部分的动态标签。
  • 较新的机制是.init_array.fini_array以及相应的DT_INIT_ARRAYDT_INIT_ARRAYSZDT_FINI_ARRAYDT_FINI_ARRAYSZ动态标签。

描述了两种机制之间的区别here

上升到源代码级别,如果用 __attribute__((constructor)) 修饰 C 函数,当对象为 [=10] 时,编译器将使用这两种机制之一使其成为 运行 =]编辑。需要动态初始化的全局C++对象的构造代码也是如此。