这取决于您的平台。
如果您使用 GCC,您可以使用 __attribute__((constructor)) 声明函数。这个函数将在你的 main 之前被调用,即使是从动态库中。
__attribute__((constructor))
void my_init()
{
/* do stuff; */
}
您可以在GCC documentation 和this SO question 中找到更多详细信息
在 VC 中也有一些方法可以做到这一点,尽管不是那么简单。 (见SO question)
编辑:如果你链接到一些第三方库,它可能会调用一些初始化函数。即使库是用 C 语言编写的。而且没有可移植和通用的方法,如何检测它。而且您可能不想弄乱它,因为库可能依赖于它在 main 启动之前被调用。
如果你真的想知道它是否调用了某些东西,你必须查看二进制文件的内部。
在 ELF 文件中,有一个部分 .init_array 包含指向将在启动时调用的函数的“指针”,并且可以使用 objdump (objdump -s -j .init_array <binary>) 转储它
我认为 Windows 中的 PE 文件中有类似的部分,但我从未使用过这些部分,抱歉。
EDIT2:
main() 函数启动您的代码。但在执行之前还有一些事情要做。当您编译您的程序时,编译器会添加一些在main() 之前执行的代码并初始化程序环境(堆栈、C 库...)。
在 Linux 下,这将主要由函数 _start 和 _init 提供。作为一项功能,您可以指示编译器在 _init 函数内调用您的一些函数。
动态库没有_start 函数,但仍有_init 将在库加载时调用。并且其中也可以包含对某些用户函数的调用。
在静态库的情况下,它变得有点复杂,因为链接器可能会删除一些函数,而这些函数从未从您的程序中调用。但是一旦它被调用(甚至间接地从库代码中调用)或者只是在库中的某个地方被引用并且从未真正调用过,它最终会在你的二进制文件中并且会在 main() 之前被调用。
关于_start 和_init 的一些信息可以是found here。
在windows下编译器和链接器是不同的,但应该以类似的方式工作。