静态链接会导致执行一些初始化例程吗? [英] can static linking result in executing some init routines?

查看:72
本文介绍了静态链接会导致执行一些初始化例程吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

不明白这件事:我在c中有一个程序 我正在将一些第二方静态库链接到该库 (据我所知,his libs也可以是一些包装器 dll)-是否可以使我的程序隐式"运行(我的意思是 而不在我的代码中显式调用它)运行一些 这些库中的初始化代码( 在我的main()例程之前执行? -还是不能?)

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代码的问题(最终关于C的问题) 没有任何c ++功能但在c ++模式下编译的代码 通过C ++编译器-链接的静态库可以用以下格式编写 任何语言)

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)

tnx回答

推荐答案

这取决于您的平台.

如果使用GCC,则可以使用__attribute__((constructor))声明函数.此功能会在您的主系统之前被调用,甚至可以从动态库中调用.

If you use GCC, you can have function declared with __attribute__((constructor)). This function WILL be called before your main, even from dynamic library.

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

您可以在 GCC文档和<一个href ="https://stackoverflow.com/questions/2053029/how-exactly-does-attribute-constructor-work">此SO问题

即使不是那么简单,也有一些方法可以在VC中进行操作. (请参阅此 SO问题)

There's some way how to do it in VC as well, even though not as simple. (See this SO question)

编辑:如果您链接到某些第三方库,则它可能会调用某些init函数.即使该库位于C中.也没有可移植且通用的方法来检测它.而且您可能不想弄混它,因为库可能依赖于它在main启动之前被调用.

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. And you probably don't want to mess with that as the library may depend it it being called before main starts.

如果您真的想找出它是否调用了某些内容,则必须查看二进制文件的内部. 在ELF文件中,有一个.init_array节,其中包含指向将在开始时调用的函数的指针",并且可以使用objdump(objdump -s -j .init_array <binary>)

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>)

我认为Windows的PE文件中有类似的部分,但抱歉,我从未使用过这些部分.

I assume there's similar section in PE files in windows, but I never worked with those, sorry.

EDIT2 : main()函数启动您的代码.但是,即使在执行之前,仍有很多事情要做.编译程序时,编译器会添加一些在main()之前执行的代码,并初始化程序的环境(堆栈,C库...).

EDIT2: The main() function starts your code. 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...).

在Linux下,这主要由功能_start_init提供.作为一项功能,您可以指示它编译器也可以在_init函数内部调用某些函数.

Under Linux this will be provided mainly by functions _start and _init. And as a feature, you can instruct it the compiler to call some your function(s) as well, inside the _init function.

动态库没有_start函数,但是在加载库时仍会调用_init.并且还可以在其中包含对某些用户功能的调用.

Dynamic library won't have the _start function, but there's still _init that will be called when the library's loaded. And a call to some user function can be included there as well.

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

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().

有关_start_init的某些信息可以是在此处找到.

Some info about _start and _init can be found here.

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

Under windows the compiler and linker is different, but it should work in a similar way.

这篇关于静态链接会导致执行一些初始化例程吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆