• 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);

  • 相关阅读:
    XCNA进阶测试20220330
    MobaXterm
    thinkpad
    华为NQA实验
    M1芯片 使用pod install 报错You may have encountered a bug in the Ruby interpreter or extension libraries. Bug reports are welcome. For details: https://www.rubylang.org/bugreport.html
    provider 跨组件状态管理
    2022年华北电力大学计算机系考研上岸同学初试经验...
    flaskrestful响应处理
    typeScript枚举
    Object.asign
  • 原文地址:https://www.cnblogs.com/wxxweb/p/2317750.html
Copyright © 2020-2023  润新知