0

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

我在这里询问关于 c 代码的问题(最终关于没有任何 c++ 功能但由 c++ 编译器以 c++ 模式编译的 c 代码 - 链接的静态库可以用任何语言编写)

tnx 回答

4

2 回答 2

1

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

于 2013-08-14T14:55:24.243 回答
1

这取决于您的平台。

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

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

您可以在GCC 文档这个 SO question中找到更多详细信息

在 VC 中也有一些方法可以做到这一点,尽管不是那么简单。(见这个问题

编辑:如果你链接到一些第三方库,它可能会调用一些初始化函数。即使库是用 C 语言编写的。而且没有可移植和通用的方法,如何检测它。而且您可能不想弄乱它,因为库可能依赖于它在 main 启动之前被调用。

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

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

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

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

动态库不具备该_start功能,但在加载库时仍然_init会调用该功能。并且其中也可以包含对某些用户函数的调用。

在静态库的情况下,它变得有点复杂,因为链接器可能会删除一些函数,而这些函数从未从你的程序中调用过。但是一旦它被调用(甚至间接地从库代码中调用)或者只是在库中的某个地方被引用并且从未真正调用过,它最终会在你的二进制文件中并且会被调用 before main()

一些关于_start和的信息_init可以在这里找到

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

于 2013-08-14T15:18:00.410 回答