use*_*404 6 c++ linux windows shared-libraries
在使用 Windows dll 时,我们应该限制 dll 边界内的内存分配/释放,因为 dll 可能使用自己的堆。所以我们有从 dll 导出分配器和自由函数。
IsomeInterface* getObject();
void freeObject(IsomeInterface *object);
Run Code Online (Sandbox Code Playgroud)
这样,对象的创建和删除将驻留在 dll 中。
linux上的共享库是否也存在这个问题?在处理共享库 (.so) 时,我们是否还需要注意在共享库中保持分配/解除分配。我在下面做了一些快速试用,它适用于 linux。相同的示例不适用于 windows dll(如果 exe 和 dll 都使用 /MD 编译以使用相同的堆,它将适用于 windows dll)。
std::vector<int> vec;
vec.push_back(42);
PassAVector(vec);
Run Code Online (Sandbox Code Playgroud)
其中PassAVector
驻留在共享库
void PassAVector(std::vector<int> &vec)
{
vec.push_back(1); // These would cause reallocation
vec.push_back(2);
vec.push_back(3);
vec.push_back(4);
vec.push_back(5);
}
Run Code Online (Sandbox Code Playgroud)
这是否意味着 unix 上的共享库与可执行文件共享堆(相当于 Windows 上的 /MD 开关)?
是否可以在 linux 上编译(某些编译器标志)共享库 (.so) 或可执行文件,以便它们开始使用不同的堆(Windows 上的 /MT 开关)并且这个问题浮出水面?
编辑:发现这似乎表明只要编译器是 gcc,就可以跨边界传递 STL。
只要您坚持使用 Glibc 或其他“正常”分配器(jemalloc、tcmalloc 等),堆状态将由所有库共享,因此您将能够释放在malloc
您想要的任何地方分配的内存。
理论上是可以绕过这个的。例如,某些库可能与malloc
/ 的自定义实现链接free
(通过 的符号脚本欺骗-Bsymbolic
),它有自己的私有堆,因此不会与程序的其他部分很好地交互。但我在现实生活中从未见过这样的事情。
STL 容器基于malloc
/free
因此也可以跨库边界传递/修改它们。当然,不同的库可以使用不同的编译器和不同的不兼容版本的 STL(例如 libstdc++、libcxx 等)进行编译,但它们的 C++ 容器类型会有所不同,并且编译器根本不允许您将它们传递给不兼容的模块。
归档时间: |
|
查看次数: |
308 次 |
最近记录: |