1

At first some introductions: I am currently working on a C++ compatibility thing which means being able to run projects with different compiler options with each other. Therefore I test with a Release DLL and a Debug application linking to that other project. Most of the problems come up when using STL so I have to assure that both projects only use their own version of the STL. Thatswhy I have a wrapper class that can be build out of std::vectors, std::lists and so on but contains only an array which is completely compatible. Now I can wrap values in an array and unpack them on the other side into a valid STL object.

Now to get a bit closer to the question: There are some classes that contain STL but also need to be wrapped into an array. So I have to wrap the inner STL object, too, which means adding a tag and saving it right next to the associated array element.

Building up this wrapper class is no problem at all but unpacking it crashes with an access violation in the vector class right here:

   const_reference operator[](size_type _Pos) const
        {   // subscript nonmutable sequence

 #if _HAS_ITERATOR_DEBUGGING
        if (size() <= _Pos)
            {
            _DEBUG_ERROR("vector subscript out of range");
            _SCL_SECURE_OUT_OF_RANGE;
            }
 #endif /* _HAS_ITERATOR_DEBUGGING */
        _SCL_SECURE_VALIDATE_RANGE(_Pos < size());

        return (*(_Myfirst + _Pos));  <---- HERE
        }

The executing code at that moment is this:

template<class T>
struct mwContainerItem
{
    T m_element;
    void * m_tag;
};

template<class T>
class mwContainer
{
    STLList ToList()
    {
        STLList l;
        for(size_t i=0; i<m_size; ++i) <---- It crashes when accessing m_size
        {
            l.push_back(m_elements[i].m_element); <---- It also crashes when accessing m_elements
        }
        return l;
    }

    mwContainerItem<T>* m_elements;
    size_t m_size;
};

The curious thing about it is I'm unpacking a std::list but it crashes in std::vector. Viewing at the whone thing I have a class contained by a std::vector and this very class contains a std::list of some basic class without STL. So unpacking means copying the outer array into a std::vector and every inner array into a std::list.

This error only occurs when I use the different compiler options, packing und unpacking in the very same project works just fine.

I really hope that anyone can help me cause I don't have any idea.

Regards

Marcel Bonzelet
  • 238
  • 2
  • 13
  • Unfortunately, I believe there's no way to get around this without compiling with the same options. See: http://stackoverflow.com/questions/4446620/returning-strings-from-dll-functions – Maxpm Jul 05 '11 at 09:39
  • There are some things you have to know about but after doing some changes to my code I was able to get it compile with this method. But it justs starts to crash on a simple 'recursion wrapping' where I don't see a problem at all if the concept works for an example without an inner STL object. – Marcel Bonzelet Jul 05 '11 at 09:44
  • @Marcel why do you consider arrays compatible with different packing options? Usually they arn't – user396672 Jul 05 '11 at 09:55
  • @user396672 They aren't? In my belief arrays are saved at the position of the pointer + i * the size of the object. I don't know why this should be different whether you use Release or Debug. But I'll check it right away. – Marcel Bonzelet Jul 05 '11 at 09:59
  • @Marcel because the size of the object may differ. Compiler adds some padding according to structure packing – user396672 Jul 05 '11 at 10:01
  • @user396672 And that is why I wrap STL objects because they have different sizes. But wouldn't you agree that if they weren't compatible my other tests would also have failed? PS: I just tested the size of my class, it's 20 bytes on both sides. – Marcel Bonzelet Jul 05 '11 at 10:08
  • @Marcel it's difficult to say... depends on the origin of your mwContainer object (how it was created, constructed, initialized with the array, etc ), it is not clear looking on your code snippet. But your own classes/structures may also cause potential errors (maybe, you are right, they arn't in this particular case) – user396672 Jul 05 '11 at 10:29
  • @user396672 I'm sorry I can't give you the full code of the array allocation. I can just give you my word that it works just fine and I guess we can exclude this as a source of error. My class is very simple and has nothing to do with a std::vector. – Marcel Bonzelet Jul 05 '11 at 10:53

1 Answers1

1

Do you really need two versions of STL? I mean, are you building the two projects with two different compilers, and two different STL implementations? When mixing debug and release versions, the problem usually comes from having two different heaps. Then, trying to release memory allocated in one module in the other, will cause an error. If this is the case you're facing, you could try another approach - have both use the same heap.

If you have control over both projects, you can export an allocator (and matching deallocator) from the DLL, and use it in the EXE. This way, memory management will be done on a single heap, and build type won't matter. You can use it in operator new, in a vector/list allocator etc.

This will probably not solve packing issues (who changes packing settings anyway?...), but it is something you want when using more than one heap.

Eran
  • 21,632
  • 6
  • 56
  • 89
  • Yes, I really need two versions of STL. Don't worry about the fact that I use two heaps because I found a way to handle memory allocation. What exactly do you mean by packing settings? I spoke of compiler setting differences such as in Debug and Release which make it hard to compile together. – Marcel Bonzelet Jul 05 '11 at 10:49
  • @Marcel Bonzelet I'm referring to data alignment, either by using [pragma pack](http://msdn.microsoft.com/en-us/library/2e70t5y1(v=VS.100).aspx), or the [/Zp](http://msdn.microsoft.com/en-us/library/xh3e3fd0(v=VS.100).aspx) switch. Make sure they are the same - if you don't know what they do, there's really no reason for them not to have the (same) default. – Eran Jul 05 '11 at 11:24
  • I use the default in both projects. – Marcel Bonzelet Jul 05 '11 at 12:13