DLL导入导出STL类对象导致崩溃的问题

问题:

从某DLL中导出一个接口函数GetDirFileIdSet用于获取目录下所有文件的ID集合。函数声明如下,该函数传入一个std::set<UINT>类对象:

void GetDirFileIdSet(std::set<UINT>& rFileIdSet);

当在VS2008中编译的“数据文件编辑器”加载了在VC6中编译的DLL,并调用到GetDirFileIdSet时发生了崩溃。

原因:

在不同的DLL或EXE中通过指针或引用操作另一个DLL或EXE中的STL类对象时,会遇到严重的程序错误,包括数据错乱或丢失。

标准C++库的多数类直接或间接的使用了静态数据成员。由于这些类是通过模板创建实例的,所以每个可执行模块(DLL或EXE)包含了有关类静态数据成员的一份Copy。当STL类中的函数成员要求操作静态数据成员时,这个类操作的静态数据是此函数成员代码所在的执行模块中的数据。由于静态成员数据在可执行模块间不能保证同步,所以前面提到的操作会导致读取失败或数据混乱和丢失。

解决方法:

1. 在创建STL类对象的模块中导出读取函数。这些函数包装了STL类对象要求的功能。这样,STL类对象只在原模块中被读取。例如:假设Program.exe需要得到Library.dll内std::deque<UINT>类对象中的一个元素,Library.dll则要导出读取函数:

__declspec(dllexport) UINT GetItem(UINT unIndex);

Program.exe就可以调用此函数来得到队列的一个元素了。

2. 从一个模块中导出模板实例,在另一个模块中导入此实例。例如:Library.dll将std::map<int, MyClass>指针传给Program.exe中的一个函数,需要在Library.dll中导出MyClass类定义和std::map<int, MyClass>类定义。然后就可以类似这样调用:

std::map<int, MyClass> *pTheMap = GiveMeTheMap();

const MyClass* pszItem = GetTheMapItemX(pTheMap, x);

posted @   Atypiape  阅读(1848)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示