How to link to the correct STL library when a third party dll is based on VC6?

I have a third party dll targeted for VC6 and .net 2003. It worked well with my old MFC application. After it was migrated to VC 2005, it throws an exception of access violation whenever the stl string information in the object is accessed. Accessing other members of the object is OK. I guess it might be linked to the stl.net library instead of the old stl library that the dll is based on. Anyone knows what is the problem  and how it can be solved

 

Thanks.



Answer this question

How to link to the correct STL library when a third party dll is based on VC6?

  • danb2005

    @Jie Chen:
    In this case if you haven't the source code of the third paty DLL you are bound forever to this STL and compiler version.

    From my point of view the interface of the compiler is not well designed. You can build a wrapper with VS2003 arround the third party DLL that converts the data in a neutral form.
    A good public DLL hides all implemenation details! And using the STL is a implementation detail.



  • gain0010

    Thank you for your speedy response. To reproduce this error, one can create a MFC dll in VS2003 with the following class:

    #pragma once

    #include "MyDef.h"

    #include <string>

    class DENOVO_INTERFACE CMySTLTest

    {

    std::string m_sMySTLString;

    public:

    CMySTLTest(void) {m_sMySTLString = "This my STL string";}

    ~CMySTLTest(void) {;}

    std::string getSTLString() { return m_sMySTLString; }

    };

    And then create a console application in VC2005 to use it as follows:

    #include "stdafx.h"

    #include "MYSTLTest.h"

    using namespace System;

    int main(array<System::String ^> ^args)

    {

    CMySTLTest oStlTest;

    String^ sString = gcnew String(oStlTest.getSTLString().c_str());

    return 0;

    }

    An access violation occured when

    oStlTest.getSTLString().c_str() is being executed. The key to reproduce this error is to create and distribute the dll in VC2003, and use the dll in VC2005.

    Thanks.

     


  • Saravana

    The structure of the STL class has been changed between VS2003 and VS2005. It seems that the allocator class is redesigned which cause the size of most of the STL class increses and become incompatible with the previous version. So I think there is no way to share them (if your dll directly return the object of the STL class, or pointer, reference, etc) between VS2003 and VS2005 executable
  • Richard McCrea

    You can not mix VS2003 and VS2005 binaries. The problems that the STL code is a template and so its code is embedded in the executable.

    Due to the fact that the implementation changes exporting STL classes from one Module compiled in 2003 and on in 2005 must lead in incompatibility and crashes.

    If you export specific classes that are not bound to a neutral binary, or are not using a neutral interface with POD types you have to use for those binaries the same compiler CRT version and libraries!



  • Tamar

    Thanks. That sounds like a reasonable solution. One follow up question is whether I should statically link those libraries or not Create a wrapper dll in VC2003 and link all the libraries statically so that the run-time knows which STL should be used
  • xudeutsch

    Thanks. It worked with my test projects. The remaining work is to wrap up the third party dll.
  • skcheng

    Because you have no influence on the third party DLL you must use the same methode to link like this file.

    If it uses shared DLLs, you can share them in your DLL too. If it is not sharing DLLs you run into a problem when you free memory. If you link the CRT statically to your DLL and free memory from another CRT (linked dynamic) you might get crashes.

    Memory can only be allocated in one module and freed in another when the CRT version is linked dynamically and both modules areusing the same version.

    Hope that clarifies it.



  • mandokev

    Thank both of you for the replies. The dll based on VC2003 is a third party dll. Unfortunately I can not do anything about it. Does that mean I have to go back to VC2003 for the time being Or maybe I should have two executables: one in VC2003 integrated with the third party dll, the other is my application in VC2005. The two executables will talk with each other. Or are there any better solutions

     

     


  • SHG

    One solution is to return const char*:

    const char* getCString() { return m_sMySTLString.c_str(); }

    But be careful about the lifetime of this pointer in relation to the object returning this pointer.

    On a related issue of performance, if this were a call between compatible versions of the Standard C++ Library, you may want to consider not creating a new instance of the string by returning a const reference to the embedded instance:

    const std::string& getSTLString() { return m_sMySTLString; }

    The code you have above would create a new string object and then copy its contents.  In earlier compilers don't implement the NVRO optimization (pre-2003, I think), this might even be done twice: once to the return value instance, and again to the callee instance.  Returning a reference avoids making any copies. 

    Brian

     


  • Night Dev

    Please post more details inlcluding a simple repro case reproducing the issue so that folks on the forums can help you.

    Thanks,
    Ayman Shoukry
    VC++ Team


  • How to link to the correct STL library when a third party dll is based on VC6?