Access Violation When Accessing an STL Object Through A Pointer or Reference In A Different DLL or E
Posted
by Yan Cheng CHEOK
on Stack Overflow
See other posts from Stack Overflow
or by Yan Cheng CHEOK
Published on 2010-03-16T02:14:50Z
Indexed on
2010/03/16
6:26 UTC
Read the original article
Hit count: 264
visual-c++
|c++
I experience the following problem while using legacy VC6. I just cann't switch to modern compiler, as I am working on a legacy code base.
http://support.microsoft.com/kb/172396
Since there are no way to export map, my planned workaround is using static linking instead of dynamic linking.
I was wondering whether you all had encountered the similar situation? What is your workaround for this?
Another workaround is to create wrapper class around the stl map, to ensure creation and accessing stl map, are within the same DLL space. Note that, fun0, which uses wrapper class will just work fine. fun1 will crash.
Here is the code example :
// main.cpp. Compiled it as exe.
#pragma warning (disable : 4786)
#include <map>
#include <string>
template <class K, class V>
class __declspec(dllimport) map_wrapper {
public:
map_wrapper();
~map_wrapper();
map_wrapper(const map_wrapper&);
map_wrapper& operator=(const map_wrapper&);
V& operator[](const K&);
const V& operator[](const K&) const;
const V& get(const K&) const;
void put(const K&, const V&);
int size() const;
private:
std::map<K, V> *m;
};
__declspec(dllimport) void fun0(map_wrapper<std::string, int>& m);
__declspec(dllimport) void fun1(std::map<std::string, int>& m);
int main () {
map_wrapper<std::string, int> m0;
std::map<std::string, int> m1;
m0["hello"] = 888;
m1["hello"] = 888;
// Safe. The we create std::map and access map both in dll space.
fun0(m0);
// Crash! The we create std::map in exe space, and access map in dll space.
fun1(m1);
return 0;
}
// dll.cpp. Compiled it as dynamic dll.
#pragma warning (disable : 4786)
#include <map>
#include <string>
#include <iostream>
/* In map_wrapper.h */
template <class K, class V>
class __declspec(dllexport) map_wrapper {
public:
map_wrapper();
~map_wrapper();
map_wrapper(const map_wrapper&);
map_wrapper& operator=(const map_wrapper&);
V& operator[](const K&);
const V& operator[](const K&) const;
const V& get(const K&) const;
void put(const K&, const V&);
int size() const;
private:
std::map<K, V> *m;
};
/* End */
/* In map_wrapper.cpp */
template <class K, class V>
map_wrapper<K, V>::map_wrapper() : m(new std::map<K, V>()) {
}
template <class K, class V>
map_wrapper<K, V>::~map_wrapper() {
delete m;
}
template <class K, class V>
map_wrapper<K, V>::map_wrapper(const map_wrapper<K, V>& map) : m(new std::map<K, V>(*(map.m))) {
}
template <class K, class V>
map_wrapper<K, V>& map_wrapper<K, V>::operator=(const map_wrapper<K, V>& map) {
std::map<K, V>* tmp = this->m;
this->m = new std::map<K, V>(*(map.m));
delete tmp;
return *this;
}
template <class K, class V>
V& map_wrapper<K, V>::operator[](const K& key) {
return (*this->m)[key];
}
template <class K, class V>
const V& map_wrapper<K, V>::operator[](const K& key) const {
return (*this->m)[key];
}
template <class K, class V>
const V& map_wrapper<K, V>::get(const K& key) const {
return (*this->m)[key];
}
template <class K, class V>
void map_wrapper<K, V>::put(const K& key, const V& value) {
(*this->m)[key] = value;
}
template <class K, class V>
int map_wrapper<K, V>::size() const {
return this->m->size();
}
// See : http://www.parashift.com/c++-faq-lite/templates.html#faq-35.15
// [35.15] How can I avoid linker errors with my template classes?
template class __declspec(dllexport) map_wrapper<std::string, int>;
/* End */
__declspec(dllexport) void fun0(map_wrapper<std::string, int>& m) {
std::cout << m["hello"] << std::endl;
}
__declspec(dllexport) void fun1(std::map<std::string, int>& m) {
std::cout << m["hello"] << std::endl;
}
© Stack Overflow or respective owner