c++ DLL接口和内存
C++ DLL interface and memory
我的问题可能与这里和这里有关:Q如果我们在堆栈上创建另一个DLL中定义的类的类型实例,它是安全的吗?
// A DLL
class DLL_EXPORT Foo;
// Target exe
int main()
{
// bad, not supposed to do this:
Foo* x = get_instance_from_dll();
delete x;
// **Question**:
// what about stack variable of type declared in the DLL?
// is this alright?
Foo x;
}
不,不安全。使用暴露c++代码的DLL有三个基本问题:
-
使用不同分配器的DLL。所以
delete
不能破坏这个物体。 -
你的编译器没有为类对象计算相同的布局。如果它的任何成员都是标准的c++库类,比如std::string或std::vector,问题就更大了。该DLL可能是用这些类的不同的版本编译的。与c++ 11之前的版本一样,它在std类实现中引起了许多变化。或者使用优化的版本构建设置,并且没有启用迭代器调试,而您启用了。
-
DLL可能抛出的跨模块边界的任何异常对象都会遇到上述两个问题。当您将DLL接口修复为安全时,这一点很容易被忽略,您不能轻松地对异常做同样的事情。
第二个项目是你的克星,你的编译器会为对象计算错误的大小,并且不会在堆栈框架上为它保留正确的空间。当实际对象大小较大时,DLL中的代码将覆盖堆栈上的其他变量,这尤其令人讨厌。很难诊断
据我所知,这里唯一的限制(因为内存管理)是new和delete必须由相同的模块调用(基本上,如果您在DLL中新建它,则在相同的DLL中删除它)。
如果你在堆栈上创建对象,这根本不是问题。
编辑:你问在构造函数中有new的情况:构造函数和析构函数将在DLL的空间中运行,所以只要new和delete在DLL中(大概在构造函数和析构函数中),那就不是问题。
也认为你应该非常认真地对待Hans的建议——如果两个编译中使用的头文件由于某种原因(不同的版本)而不同,或者模块是用不同的编译器编译的,或者编译器设置在某些方面不同,那么你很容易很难诊断bug。
如果你没有使用相同的工具构建两个模块并一起发布,你应该不会遇到任何问题。
- 将字符串存储在c++中的稳定内存中
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- Win32编译器选项和内存分配
- 当vector是tje全局变量时,c++中vector的内存管理
- 带内存和隔离功能的SQLite
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 迭代时从向量和内存中删除对象
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 使用没有堆内存分配的接口的框架应用程序?
- SQLite C/C++ 接口:将数据插入表时内存增加
- C 接口到线性内存缓冲区
- 我是否必须在C 接口的OPENCV C包装器中自由分配的内存
- 为函数设计接口时,强制用户(客户端)提供内存区域 >= 所需大小。怎么做,是好是坏?
- Python-C++ 接口中的内存泄漏
- COM / DCOM:服务器存根不会为现有接口中的新方法分配内存
- 共享内存系统性能的消息传递接口
- MATLAB-C 接口:内存上的访问冲突错误
- 导入"RegExp.tlb" C++ COM 接口是否在进程之间隐式共享内存?
- c++ DLL接口和内存
- std::list带有接口的内存泄漏