Search code examples
c++windowsvisual-c++-6visual-c++-2008name-decoration

Using C++ DLLs with different compiler versions


This question is related to "How to make consistent dll binaries across VS versions ?"

  • We have applications and DLLs built with VC6 and a new application built with VC9. The VC9-app has to use DLLs compiled with VC6, most of which are written in C and one in C++.
  • The C++ lib is problematic due to name decoration/mangling issues.
  • Compiling everything with VC9 is currently not an option as there appear to be some side effects. Resolving these would be quite time consuming.
  • I can modify the C++ library, however it must be compiled with VC6.
  • The C++ lib is essentially an OO-wrapper for another C library. The VC9-app uses some static functions as well as some non-static.

While the static functions can be handled with something like

// Header file
class DLL_API Foo
{
    int init();
}

extern "C"
{
    int DLL_API Foo_init();
}

// Implementation file
int Foo_init()
{
    return Foo::init();
}

it's not that easy with the non-static methods.

As I understand it, Chris Becke's suggestion of using a COM-like interface won't help me because the interface member names will still be decorated and thus inaccessible from a binary created with a different compiler. Am I right there?

Would the only solution be to write a C-style DLL interface using handlers to the objects or am I missing something? In that case, I guess, I would probably have less effort with directly using the wrapped C-library.


Solution

  • Interface member names will not be decorated -- they're just offsets in a vtable. You can define an interface (using a C struct, rather than a COM "interface") in a header file, thusly:

    struct IFoo {
        int Init() = 0;
    };
    

    Then, you can export a function from the DLL, with no mangling:

    class CFoo : public IFoo { /* ... */ };
    extern "C" IFoo * __stdcall GetFoo() { return new CFoo(); }
    

    This will work fine, provided that you're using a compiler that generates compatible vtables. Microsoft C++ has generated the same format vtable since (at least, I think) MSVC6.1 for DOS, where the vtable is a simple list of pointers to functions (with thunking in the multiple-inheritance case). GNU C++ (if I recall correctly) generates vtables with function pointers and relative offsets. These are not compatible with each other.