当使用Windows dll时,我们应该限制内存分配/释放在dll边界内,因为dll可能正在使用它自己的堆。因此,我们需要导出分配器和从dll中释放函数。
IsomeInterface* getObject();
void freeObject(IsomeInterface *object);
这样,对象的创建和删除将位于dll内部。
在linux上共享库(.so)也存在这个问题吗?在处理共享库时,我们是否也需要注意保持分配/释放在共享库内部。 我尝试了以下快速测试,在linux上可以工作。相同的例子在Windows DLL上不起作用(如果exe和dll都编译为/ MD以利用相同的堆,则Windows DLL将起作用)。
std::vector<int> vec;
vec.push_back(42);
PassAVector(vec);
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);
}
这是否意味着在unix上共享库与可执行文件共享堆(相当于windows上的/MD开关)?
是否可以通过在Linux上编译(一些编译器标志)共享库(.so)或可执行文件,使它们开始使用不同的堆(类似于Windows的/MT开关),并出现此问题?
编辑:找到这个,似乎表明跨边界传递STL是可以的,只要编译器是gcc。
PassAVector
遭遇了一个不同的问题,与操作系统无关:C++ 没有标准 ABI。在模块边界传递 C++ 对象从来没有得到支持。 - IInspectablestd::vector
实现不同,因此一切都无法预测。在这里,我特别想了解堆的情况。在Windows上,模块可以有不同的堆,即使使用相同的编译器/配置,如果分配跨越边界,也无济于事。对于gcc而言,堆的情况如何? - user3819404