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: 321
        
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