静态链接会导致执行一些初始化例程吗?

时间:2013-08-14 14:47:21

标签: c++ c linker shared-libraries static-libraries

不明白这件事:我在c中得到了一个程序 我正在将一些第二方静态库链接到那个 (据我所知,这个libs也可以是一些包装器 dlls) - 它能否使我的程序“隐含地”(我的意思是 没有在我的代码中显式调用)运行一些 来自那些libs的初始化代码(将会 在我的main()例程之前执行? - 或者它不能?)

我在这里问关于c代码(最后关于c 代码没有任何c ++功能,但在c ++模式下编译 通过c ++编译器 - 可以编写链接的静态库 任何语言)

tnx for answer

2 个答案:

答案 0 :(得分:1)

任何类型的链接库都无法在没有c或c ++中代码的显式调用的情况下运行初始化代码。

答案 1 :(得分:1)

这取决于您的平台。

如果您使用GCC,则可以使用__attribute__((constructor))声明函数。此函数在您的主函数之前调用,甚至可以从动态库调用。

__attribute__((constructor))
void my_init()
{
    /* do stuff; */
}

您可以在GCC documentationthis SO question

中找到更多详细信息

在VC中也有一些方法可以做到这一点,即使不是那么简单。 (见SO question

编辑:如果您链接到某个第三方库,它可能会调用一些初始化函数。即使库在C中。并且没有便携式和通用方式,如何检测它。你可能不想搞砸了,因为库可能依赖它在主要启动之前调用它。

如果你真的想知道它是否会调用某些东西,你必须查看二进制文件。 在ELF文件中,有一个部分.init_array包含将在开始时调用的函数的“指针”,它可以使用objdump(objdump -s -j .init_array <binary>)转储

我假设Windows中的PE文件中有类似的部分,但我从未与这些部分合作过,抱歉。

<强> EDIT2 main()函数启动您的代码。但是在它被执行之前还有其他事情要做。编译程序时,编译器会添加一些在main()之前执行的代码,并初始化程序环境(stack,C library ...)。

在Linux下,这将主要由函数_start_init提供。作为一个功能,您可以指示编译器在_init函数内调用一些函数。

动态库不具有_start功能,但在加载库时仍会调用_init。此外,还可以包含对某些用户功能的调用。

对于静态库,它会变得有点复杂,因为链接器可能会删除某些函数,而这些函数从未从程序中调用过。但是一旦它被调用(甚至间接地从库代码中调用)或者只是在库中的某个地方被引用而从未实际调用过,它将以二进制形式结束并在main()之前被调用。

有关_start_init的一些信息可以是found here

在Windows下,编译器和链接器是不同的,但它应该以类似的方式工作。