Windows C++下链接库的静态初始化

Static initialization in linked library under Windows C++

本文关键字:静态 初始化 链接 C++ Windows      更新时间:2023-10-16

我有一个配置,它有一个库和一个控制台应用程序。他们现在都是光秃秃的。我使用的是Visual Studio 2010,库和控制台应用程序都静态链接到运行时。控制台应用程序还链接到库。

在库中,我可以将此代码添加到源文件中:

class MyClass
{
public:
    MyClass()
    {
        printf("MyClass loadedn");
    }
};
class MyClass2
{
public:
    static MyClass my_class;
};
MyClass MyClass2::my_class;

现在,我的理解是my_class应该在main()之前的某个时刻初始化。然而,它从未发生过(因为我没有收到打印的信息)。

然而,我可以使用两种不同的方法对其进行初始化:

  1. 将代码放在控制台应用程序中。这样做肯定会调用printf()语句
  2. 修改MyClass2以包含从库中的全局变量调用的静态函数,并在控制台应用程序的main()中使用该全局变量

上面#2的例子:

库文件:

class MyClass
{
public:
    MyClass()
    {
        printf("MyClass loadedn");
    }
};
class MyClass2
{
public:
    static MyClass my_class;
    static int Ping();
};
MyClass MyClass2::my_class;
int my_global = MyClass2::Ping();

控制台应用程序文件:

extern int my_global;
int main()
{
    printif("%d", my_global);
}

Windows是否试图通过延迟加载链接库的静态变量来帮助我??或者有我设置的编译器设置吗?这种行为完全出乎我的意料。

是最终可执行文件的"库文件"部分。如果是静态链接库中的对象文件,它将只是一部分如果最终可执行文件解析了未解析的外部符号。(这是库的定义。)如果永远不要在对象文件中使用任何符号,它不会是你的可执行文件,就好像源文件不是应用程序。

如果库是动态加载的,情况会稍微不同的.dll作为一个单元(而不是对象文件)由对象文件,所以它实际上不是一个库),但如果没有将通过加载DLL来解析的未解析符号,它也不会被加载。

您可能想要做的是针对对象文件进行链接,并且而不是针对库。在Visual Studio中,这意味着将所有资源放在同一个项目中。或你可以将库链接为.dll,然后使用显式加载LoadLibrary。(这就是我们为图书馆所做的被引用,因为它们具有静态对象的构造函数它们自己注册。)