Symptoms

When accessing an STL object created in one DLL or EXE through a pointer or reference in a different DLL or EXE, you may experience an access violation or other serious program errors including the appearance of data corruption or data loss.

Cause

Most classes in the Standard C++ Libraries use static data members directly or indirectly. Since these classes are generated through template instantiation, each executable image (usually with DLL or EXE file name extensions) will contain its own copy of the static data member for a given class. When a method of the class that requires the static data member is executed, it uses the static data member in the executable image in which the method code resides. Since the static data members in the executable images are not in sync, this action could result in an access violation or data may appear to be lost or corrupted.

Resolution

  1. Export accessor methods from the executable image that created the STL object. These methods wrap the required functionality of the STL object. In this way, the STL object will only be directly accessed inside a single executable image. For example, suppose MyProgram.EXE needs to get the next element in deque<MyClass> that resides in MyLibrary.DLL. MyLibrary.DLL could export an accessor method, MyClass* DequeNextItem (/*...*/). Then MyProgram.EXE could execute this method to get the next item in the deque. See the code sample below for a more complete example.

    This option works for STL objects that are either global, static, or static data members of a class that are not exported from a DLL. This option will not work for non-static data members of a class that are exported from a DLL or for automatic data.

  2. Export the template class instantiation from one executable image and import it into the other executable images. For example, if MyLibrary.DLL passes a pointer to vector<MyClass> back to a function in MyProgram.EXE, then export the classes MyClass and vector<MyClass> from MyLibrary.DLL. Then import these classes into MyProgram.EXE. By doing this, you will have one copy of the static class members residing in MyLibrary.DLL. For more information about exporting and importing STL, click the following article number to view the article in the Microsoft Knowledge Base:
    168958How to export STL components inside and outside of a class

Status

This behavior is by design.

More Information

Steps to reproduce the behavior

   //---------------------------------------------------------
// AVEXE.CPP
// Compile options needed: /GX
#pragma warning (disable : 4786)
#include <map>
#include <string>
#include <stdio.h> __declspec(dllimport)
std::map<int,std::string>* GiveMeAMap(int n); __declspec(dllimport)
void ShowMeTheMap(std::map<int,std::string> *amap); __declspec(dllexport)
const char* MapItemX (std::map<int,std::string> *m, int x); int main () { // Create the map in the DLL
int x = 6;
std::map<int,std::string> *p = GiveMeAMap(x); // Display the contents of the map from the DLL
printf("Showing contents from the DLL\n");
ShowMeTheMap(p); // Display the contents of the map from the EXE
// using the accessor function from the DLL so we
// aren't directly accessing the map
printf("Showing contents from the EXE using accessor\n");
int i = x;
while (i--) {
printf("%d = %s\n",i,MapItemX(p,i));
} // Access Violation when accessing the map that
// was created in the DLL from the EXE
printf("Showing contents from the EXE directly\n");
while (x--) {
printf("%d = %s\n",x,(*p)[x].c_str());
} return 0;
} //---------------------------------------------------------
// AVDLL.CPP
// Compile options needed /GX
#pragma warning (disable : 4786)
#include <map>
#include <string>
#include <stdlib.h> // Create the map here in the DLL
__declspec(dllexport)
std::map<int,std::string>* GiveMeAMap(int n) {
std::map<int,std::string> *m = new std::map<int,std::string>;
while(n--) {
char b[33];
itoa(n,b,2);
(*m)[n] = std::string(b);
}
return m;
} // We can access the map without error from the executable
// image where the map was created
__declspec(dllexport)
void ShowMeTheMap(std::map<int,std::string> *p) {
int x = p->size();
while (x--) {
printf("%d = %s\n",x,(*p)[x].c_str());
}
} // An accessor method to return the associated C string
// for key x
__declspec(dllexport)
const char* MapItemX (std::map<int,std::string> *m, int x) {
return (*m)[x].c_str();
}
 
Properties

Article ID: 172396 - Last Review: Sep 2, 2005 - Revision: 1

You may experience an access violation when you access an STL object through a pointer or reference in a different DLL or EXE的更多相关文章

  1. 如何捕获access violation异常

    文章目录 access violation的由来 access violation的实例 Win32 exception SEH异常与C++标准异常 捕获方法 1.access violation的由 ...

  2. 动态调用DLL函数有时正常,有时报Access violation的异常

    动态调用DLL函数有时正常,有时报Access violation的异常 typedef int (add *)(int a,int b); void test() {     hInst=LoadL ...

  3. 解决 “access violation at address xxxxxxxxx”错误

    在进行磁盘整理的时候,打开Foxmail的时候出现了“access violation at address32383137”错误 和“access violation at address00000 ...

  4. STM32 KEIL不能输入仿真引脚端口error 65: access violation at 0x40021000 : no 'read' permission

    使用MDK自己创建一个STM32F103ZE核的项目 加入源码后编译,正常,在线仿真单步执行出现如下问题 error 65: access violation at 0x40021000 : no ' ...

  5. QDomDocument Access violation writing location

    今天犯了一个非常2的错误! 为了将面板参数保存起来,选择用QDomDocument构造Dom树,然后用doc.toString()方法返回符合xml格式的QString.如: QString CutF ...

  6. Access Violation at address 00000000.Read of address 00000000 解决办法

    是数组越标或没有初始化某个对象之类的问题,搂住细细检查一下代码, 使用指针前未做检查,而这个指针未初始化. 可能是new后没有delete,这样出现溢出的可能性比较大     检查代码或者跟踪试试 使 ...

  7. u-boot TFTP: &#39;Access violation&#39; (2)

    今天做tftp下载时间会遇到以下问题. --->8--- Load address: 0x20000000 Loading: * TFTP error: 'Access violation' ( ...

  8. laravel migrate时报错:Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes

    今天在学习laravel的路由模型绑定时,在按照文档执行php artisan migrate时报错. In Connection.php line 664: SQLSTATE[42000]: Syn ...

  9. std::vector push_back报错Access violation

    C/C++ code   ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include < ...

随机推荐

  1. DES对 json 、http参数加密解密算法

    网上众多大神们的众多方式实现加解密操作及保障数据安全性.今天无意中发现一篇以 DES加密解密算法.摘抄如下 工具类: import java.security.SecureRandom; import ...

  2. Socket编程 - API

    基础知识部分:http://www.cnblogs.com/Jimmy1988/p/7839940.html 1. 基本流程 Process Client Server Comment socket( ...

  3. SQL存储过程使用方法

    public void findflight() { // 创建参数 IDataParameter[] parameters = { ) , new SqlParameter("@Name& ...

  4. item2 快捷键

    快捷键 ⌘ + Click:可以打开文件,文件夹和链接 ⌘ + n:新建窗口 ⌘ + t:新建标签页 ⌘ + w:关闭当前页 ⌘ + 数字 & ⌘ + 方向键:切换标签页 ⌥⌘ + 数字:切换 ...

  5. node.js和JavaScript的关系

    node.js是一个基于 Chrome V8 引擎的 JavaScript 运行时环境. 一.类比JavaScript和java JavaScript java V8 JVM node.js JRE ...

  6. macbook usb口突然不能用 解决方法

    1.先按shift+ctrl+opt+开机键,等待10秒,着10秒是没有反应的,屏幕不会亮,系统不会跑起来.2.10秒过后松开所以的键.3.再按opt+cmd+r+p接着按开机键,这时电脑会不断重启, ...

  7. python 字符串居中

    下面的代码可以让字符串居中,左对齐和右对齐,字符串长度设置为50,居中后左右补充空格,右对齐会在左侧补充空格 string1 = "Now I am here." print( s ...

  8. Codeforces 1097 Alex and a TV Show

    传送门 除了操作 \(3\) 都可以 \(bitset\) 现在要维护 \[C_i=\sum_{gcd(j,k)=i}A_jB_k\] 类比 \(FWT\),只要求出 \(A'_i=\sum_{i|d ...

  9. iview select下拉bug

    1场景:弹框内有一个下拉组件(支持搜索),当选择完数据后弹框关闭,再次打开后,下拉框内的数据是刚才选中的数据.原因:分析后觉得是搜索内容没有清空,导致下拉的数据只有一个解决:调用下setQuery方法 ...

  10. Spring Boot—21Actuator--监控

    https://docs.spring.io/spring-boot/docs/2.0.1.RELEASE/reference/htmlsingle/ pom.xml <dependency&g ...