动态库和主程序中的静态类变量[重复]

Posted

技术标签:

【中文标题】动态库和主程序中的静态类变量[重复]【英文标题】:Static Class Variables in Dynamic Library and Main Program [duplicate] 【发布时间】:2011-02-07 04:01:36 【问题描述】:

我正在开发一个包含静态 stl 容器类的“A”类的项目。这个类包含在我的主程序和 .so 文件中。该类使用默认(隐式,未声明)构造函数/析构函数。主程序使用 dlopen() 加载 .so 文件,并在其析构函数中调用 dlclose()。当 glibc 调用静态类成员变量的析构函数时,程序在 main 退出后崩溃。问题似乎是调用dlclose()时,调用了静态变量的析构函数,然后当main exits()时glibc也调用析构函数,导致double free。

我有两个问题,分别是: 1)在这种特殊情况下,为什么没有静态变量的两个副本(是的,我知道这听起来有些荒谬,但是由于主程序和 .so 文件都有一个单独编译的“A”,所以它们不应该都有一个?) 2) 有没有什么办法可以解决这个问题而不需要重写类'A'而不包含静态成员变量?

【问题讨论】:

静态的析构函数是从dlclose() 中调用的吗?我遇到了类似的问题,但是在调用静态析构函数之前代码段未映射。 你误诊了问题——共享库有自己的静态变量。 是的,他们有,当我查看符号表时,共享库确实有自己的符号。但是,似乎从未使用过 .SO 的符号。对于主程序中的符号,静态构造函数和析构函数被调用了两次。这可能是由于 extern "C" 函数声明导致的一些坏名修改的结果吗? 【参考方案1】:

这个问题已在我发布的另一个问题中得到解决。基本上静态变量确实有两个副本——一个在主程序中,一个在共享库中,但是运行时链接器将两个副本解析为主程序副本。有关详细信息,请参阅此问题:

Main Program and Shared Library initializes same static variable in __static_initialization_and_destruction_0

【讨论】:

【参考方案2】:

我相信 STL 类总是动态创建的,因此您实际上不能称它们为静态的。它们存在于堆上。如果将成员传递给函数,则将副本放入静态内存。您必须创建自己的析构函数,显式删除 stl 一次。

【讨论】:

静态,我的意思是静态链接(例如,我的主程序包含类'A'的代码副本,我的.so包含类'A'的代码副本)与静态前缀。例如:A 类 public: static list slist;

以上是关于动态库和主程序中的静态类变量[重复]的主要内容,如果未能解决你的问题,请参考以下文章

动态库和静态库

GCC 编译使用动态链接库和静态链接库--及先后顺序----及环境变量设置总结

Linux下的静态库和动态库

C语言中静态库和动态库的区别,如何使用它们

动态链接库和静态链接库的区别简述

单例模式 静态库和动态库的区别