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

Filed under:
|

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

Related posts about visual-c++

Related posts about c++