简体   繁体   English

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

[英]can static linking result in executing some init routines?

do not understand this thing: I got a program in c and I am linking some second party static libs to that (as far as I know lhis libs can be also some wrappers on dlls) - does it can bring my program to 'implicitely' (I mean without explicit call to that in my code) run some initialisation code from whithin those libs (that will execute before my main() routine ? - or it cannot ?) 不明白这件事:我在c中得到了一个程序,我将一些第二方静态库链接到那个(据我所知,这个库也可以是dll上的一些包装器) - 是否可以使我的程序“隐含” (我的意思是没有在我的代码中明确调用它)从那些libs中运行一些初始化代码(它将在我的main()例程之前执行? - 或者它不能?)

I am asking here about about c code (eventualy about c code without any c++ feature but compiled in c++ mode by c++ compiler - linked static libs can be written in any language) 我在这里问关于c代码(最终关于没有任何c ++特性的c代码,但是由c ++编译器在c ++模式下编译 - 链接的静态库可以用任何语言编写)

tnx for answer tnx的答案

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

It depends on your platform. 这取决于您的平台。

If you use GCC, you can have function declared with __attribute__((constructor)) . 如果使用GCC,则可以使用__attribute__((constructor))声明函数。 This function WILL be called before your main, even from dynamic library. 此函数在main之前调用,甚至可以从动态库调用。

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

You can find more details in GCC documentation and in this SO question 您可以在GCC文档此SO问题中找到更多详细信息

There's some way how to do it in VC as well, even though not as simple. 虽然不是那么简单,但在VC中也有一些方法可以做到这一点。 (See this SO question ) (见这个问题

EDIT : If you link to some third party library, it may call some init function. 编辑 :如果您链接到某些第三方库,它可能会调用一些初始化函数。 Even if the library is in C. And there's no portable and generic way, how to detect it. 即使库在C中。并且没有便携式和通用方式,如何检测它。 And you probably don't want to mess with that as the library may depend it it being called before main starts. 而且你可能不想搞砸它,因为库可能依赖于它在主要启动之前被调用。

If you really want to find out if it calls something, you'd have to look inside the binary. 如果你真的想知道它是否会调用某些东西,你必须查看二进制文件。 In ELF files, there's a section .init_array containing "pointers" to functions that will be invoked at start and it can be dumped using objdump ( objdump -s -j .init_array <binary> ) 在ELF文件中,有一个部分.init_array包含将在开始时调用的函数的“指针”,它可以使用objdump转储( objdump -s -j .init_array <binary>

I assume there's similar section in PE files in windows, but I never worked with those, sorry. 我假设在Windows中的PE文件中有类似的部分,但我从来没有和那些人一起工作,对不起。

EDIT2 : The main() function starts your code. EDIT2main()函数启动你的代码。 But there's stuff to do even before it's executed. 但是在它被执行之前还有其他事情要做。 When you compile your program, the compiler adds some code that is executed before the main() and initializes environment for program (stack, C library...). 编译程序时,编译器会添加一些代码,这些代码在main()之前执行并初始化程序环境(stack,C library ...)。

Under Linux this will be provided mainly by functions _start and _init . 在Linux下,这将主要由函数_start_init And as a feature, you can instruct it the compiler to call some your function(s) as well, inside the _init function. 作为一个功能,您可以指示编译器在_init函数内调用一些函数。

Dynamic library won't have the _start function, but there's still _init that will be called when the library's loaded. 动态库不具有_start函数,但仍然会在库加载时调用_init And a call to some user function can be included there as well. 此外,还可以包含对某些用户功能的调用。

In the case of static library it gets a bit more complicated, as the linker may remove some functions, when they're never called from you program. 在静态库的情况下,它会变得有点复杂,因为链接器可能会删除某些函数,而它们从未从您的程序中调用过。 But once it's called (even indirectly from the library code) or just referenced somewhere in the library and never actually called, it will end up in you binary and will be called before main() . 但是一旦它被调用(甚至间接来自库代码)或只是在库中某处引用并且从未实际调用过,它将以二进制结束并在main()之前被调用。

Some info about _start and _init can be found here . 有关_start_init一些信息可以在这里找到

Under windows the compiler and linker is different, but it should work in a similar way. 在windows下,编译器和链接器是不同的,但它应该以类似的方式工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM