zoukankan      html  css  js  c++  java
  • 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);

  • 相关阅读:
    Linux安装nginx
    Linux安装vsftp服务
    maven的Tomcat插件使用
    Mybatis逆向工程生成代码
    千里之行,始于足下
    java 通过反射获取注解
    天气预报需要用到的jar包
    JDBC 利用反射 配置文件
    从网页下载图片的代码
    装箱/拆箱 对象排序
  • 原文地址:https://www.cnblogs.com/wxxweb/p/2317750.html
Copyright © 2011-2022 走看看