不明白这件事:我在c中得到了一个程序 我正在将一些第二方静态库链接到那个 (据我所知,这个libs也可以是一些包装器 dlls) - 它能否使我的程序“隐含地”(我的意思是 没有在我的代码中显式调用)运行一些 来自那些libs的初始化代码(将会 在我的main()例程之前执行? - 或者它不能?)
我在这里问关于c代码(最后关于c 代码没有任何c ++功能,但在c ++模式下编译 通过c ++编译器 - 可以编写链接的静态库 任何语言)
tnx for answer
答案 0 :(得分:1)
任何类型的链接库都无法在没有c或c ++中代码的显式调用的情况下运行初始化代码。
答案 1 :(得分:1)
这取决于您的平台。
如果您使用GCC,则可以使用__attribute__((constructor))
声明函数。此函数将在您的主函数之前调用,甚至可以从动态库调用。
__attribute__((constructor))
void my_init()
{
/* do stuff; */
}
您可以在GCC documentation和this 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下,编译器和链接器是不同的,但它应该以类似的方式工作。