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. Swift基础语法之变量函数

    import Foundation //变量声明使用 //使用 let 来声明常量,使用 var 来声明变量 常量只能为它赋值一次 let name="cuiyw"; var ag ...

  2. bootstrap栅格系统的属性及使用

    栅格系统 媒体查询 在栅格系统中,我们在 Less 文件中使用以下媒体查询(media query)来创建关键的分界点阈值. 小屏幕(平板,大于等于 768px) @media (min-width: ...

  3. 傻瓜式解读koa中间件处理模块koa-compose

    最近需要单独使用到koa-compose这个模块,虽然使用koa的时候大致知道中间件的执行流程,但是没仔细研究过源码用起来还是不放心(主要是这个模块代码少,多的话也没兴趣去研究了). koa-comp ...

  4. COM线程模型的行为

    原文:https://msdn.microsoft.com/library/ms809971.aspx Behavior of the COM Threading Models COM线程模型的行为 ...

  5. SpringBoot+JPA+cache入门

    在pom.xml中加入如下依赖 <dependency> <groupId>org.springframework.boot</groupId> <artif ...

  6. Hadoop shell 一查就会

    Hadoop shell 命令有三种格式 hdfs + dfs (必须是dfs) Hadoop + dfs Hadoop + df 命令 说明 hadoop 版本查看 hadoop version h ...

  7. java计算机二级笔记

    java.applet.AppletAppletHTMLAppletextends Appletextends AppletprintinitcalendarCalendarCalendar 日历类J ...

  8. vue setTimeout--延迟操作

    有时候我们在查询后要做某些事情,例如我查询的时候要根据某个值再去查询某些东西并和这些值一起显示的时候,我们可以对渲染数据的操作进行延迟,因为代码执行的速度是很快的而访问数据的操作相对于渲染的速度慢得多 ...

  9. Windows上只复制目录结构不复制文件

    xcopy /T /E D:\filetest\FB\BK\bs\ D:\filetest\asdf

  10. CSS reset的审视

    by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/wordpress/?p=758 一.CSS re ...