none
[help] Is there a way to change VC++ compiler name mangling scheme?

    Question

  • Hi,

    I have a VC++ 6 project which depends on some VC6 libs(dynamically linked to VC++ DLLs).
    Now I want to build the project with VC++ 2010. The compiling is ok, but linking failed due to some unresolved function symbols.

    The error output is:
    error LNK2001: unresolved external symbol "int __cdecl LogPrintf(wchar_t const *,...)" (?LogPrintf@@YAHPB_WZZ)

    I opened the VC6 lib with IDA Pro and get a different function name:
    ?LogPrintf@@YAHPBGZZ

    The function prototype is:
    BOOL LogPrintf(LPCWSTR pszMsg, ...);

    Is the name mangling scheme of VC6 compiler incompatible with that of VC2010 compiler?
    Is there any workaround? Thank you!

    Tuesday, June 22, 2010 11:49 AM

Answers

  • bozhang wrote:

    I have a VC++ 6 project which depends on some VC6 libs(dynamically  linked to VC++ DLLs).
    Now I want to build the project with VC++ 2010. The compiling is ok,  but linking failed due to some unresolved function symbols.

    The error output is:
    error LNK2001: unresolved external symbol "int __cdecl  LogPrintf(wchar_t const *,...)" (?LogPrintf@@YAHPB_WZZ
    <mailto:?LogPrintf@@YAHPB_WZZ>)

    I opened the VC6 lib with IDA Pro and get a different function name:
    ?LogPrintf@@YAHPBGZZ mailto:?LogPrintf@@YAHPBGZZ

    The immediate fix is to compile the DLL with /Zc:wchar_t- switch  (Project | Properties | C/C++ | Language | Treat wchar_t as Built-in  Type = No). This turns wchar_t from being a native type to being a  typedef for unsigned short, just as it was in VC6.

    The Right Thing To Do (TM) is to use .def file to export non-decorated  names from your DLL to begin with.


    Igor Tandetnik

    • Marked as answer by bozhang Wednesday, June 23, 2010 5:30 AM
    Tuesday, June 22, 2010 12:04 PM

All replies

  • bozhang wrote:

    I have a VC++ 6 project which depends on some VC6 libs(dynamically  linked to VC++ DLLs).
    Now I want to build the project with VC++ 2010. The compiling is ok,  but linking failed due to some unresolved function symbols.

    The error output is:
    error LNK2001: unresolved external symbol "int __cdecl  LogPrintf(wchar_t const *,...)" (?LogPrintf@@YAHPB_WZZ
    <mailto:?LogPrintf@@YAHPB_WZZ>)

    I opened the VC6 lib with IDA Pro and get a different function name:
    ?LogPrintf@@YAHPBGZZ mailto:?LogPrintf@@YAHPBGZZ

    The immediate fix is to compile the DLL with /Zc:wchar_t- switch  (Project | Properties | C/C++ | Language | Treat wchar_t as Built-in  Type = No). This turns wchar_t from being a native type to being a  typedef for unsigned short, just as it was in VC6.

    The Right Thing To Do (TM) is to use .def file to export non-decorated  names from your DLL to begin with.


    Igor Tandetnik

    • Marked as answer by bozhang Wednesday, June 23, 2010 5:30 AM
    Tuesday, June 22, 2010 12:04 PM
  • Igor Tandetnik wrote:
    > bozhang wrote:
    >
    > I have a VC++ 6 project which depends on some VC6 libs(dynamically
    > linked to VC++ DLLs).
    > Now I want to build the project with VC++ 2010. The compiling is
    > ok, but linking failed due to some unresolved function symbols.
    >
    > The error output is:
    > error LNK2001: unresolved external symbol "int __cdecl
    > LogPrintf(wchar_t const *,...)" (?LogPrintf@@YAHPB_WZZ
    > <mailto:?LogPrintf@@YAHPB_WZZ>)
    >
    > I opened the VC6 lib with IDA Pro and get a different function name:
    > ?LogPrintf@@YAHPBGZZ mailto:?LogPrintf@@YAHPBGZZ
    >
    > The immediate fix is to compile the DLL with /Zc:wchar_t- switch (...)
    >
    >
    > The Right Thing To Do (TM) is to use .def file to export non-decorated
    > names from your DLL to begin with.
    >
     
    Hmmm ... this statement confuses me. Given a C interface we would use
    extern "C" to prevent decoration and given a C++ interface, we do rely
    on the correct decoration, or otherwise it will just "crash" at runtime
    if things do not match up. Or am I confusing things?
     
    cheers,
    Martin
     
    Tuesday, June 22, 2010 2:11 PM
  • It Will not crash it will generate linking error to you.

    Thanks


    Rupesh Shukla www.experts-linked.com
    Tuesday, June 22, 2010 5:06 PM
  • Martin Ba. wrote:

    The Right Thing To Do (TM) is to use .def file to export  non-decorated
    names from your DLL to begin with.

    Hmmm ... this statement confuses me. Given a C interface we would use
    extern "C" to prevent decoration

    extern "C" doesn't remove all decoration. You still have an underscore  in front, or @<some_number> at the end, depending on the calling  convention. You need a .def file to remove those. I don't remember if  you also need to mark exported functions with extern "C" - maybe you do.

    and given a C++ interface, we do rely
    on the correct decoration

    It's a bad idea to export C++ interface from a DLL in the first place.  Chances are high a DLL like that won't work with an EXE built by a  different compiler version.


    Igor Tandetnik

    Tuesday, June 22, 2010 7:11 PM
  • Well, the problem gets solved by taking the advice of Igor Tandetnik. I just set "Treat WChar_t As Built in Type" to "No" in VS2010, then all is OK.

    The libs (generated by VC6) which cause the trouble are maintained by other teams, so I have no source code for them and it will take them lot of time to rebuild the libs with VC2010.

    Thank you all!

    Wednesday, June 23, 2010 5:29 AM
  • Igor Tandetnik wrote:
    > Martin Ba. wrote:
    >
    > The Right Thing To Do (TM) is to use .def file to export
    > non-decorated
    > names from your DLL to begin with.
    >
    > Hmmm ... this statement confuses me. Given a C interface we would use
    > extern "C" to prevent decoration
    >
    > extern "C" doesn't remove all decoration. You still have an underscore
    > in front, or @<some_number> at the end, depending on the calling
    > convention. You need a .def file to remove those. I don't remember if
    > you also need to mark exported functions with extern "C" - maybe you do.
     
    Ah yes. It might be noted that the combination ob extern "C" and
    __declspec(dllexport) will lead to undecorated names (no underscore).
     
    >
    > and given a C++ interface, we do rely
    > on the correct decoration
    >
    > It's a bad idea to export C++ interface from a DLL in the first place.
    > Chances are high a DLL like that won't work with an EXE built by a
    > different compiler version.
    >
     
    C++ DLL interface are neccessarily
     
    Wednesday, June 23, 2010 8:14 AM
  • Martin Ba. wrote:
    > Igor Tandetnik wrote:
    > > Martin Ba. wrote:
    > >
    > > The Right Thing To Do (TM) is to use .def file to export
    > > non-decorated
    > > names from your DLL to begin with.
    > >
    > > Hmmm ... this statement confuses me. Given a C interface we would use
    > > extern "C" to prevent decoration
    > >
    > > extern "C" doesn't remove all decoration. You still have an underscore
    > > in front, or @<some_number> at the end, depending on the calling
    > > convention. You need a .def file to remove those. I don't remember if
    > > you also need to mark exported functions with extern "C" - maybe you do.
    >
    > Ah yes. It might be noted that the combination ob extern "C" and
    > __declspec(dllexport) will lead to undecorated names (no underscore).
    >
    > >
    > > and given a C++ interface, we do rely
    > > on the correct decoration
    > >
    > > It's a bad idea to export C++ interface from a DLL in the first place.
    > > Chances are high a DLL like that won't work with an EXE built by a
    > > different compiler version.
    > >
    >
    > C++ DLL interface are neccessarily
    >
     
    ... grml - stupid news client ...
     
    C++ DLL interfaces are neccessarily incompatible across compiler
    versions and switches.
    That does not mean it's a bad idea to use exported C++ interfaces - it
    just means you can only use them when you compile everything together.
    (Like when you split some modules of an app into DLLs.)
     
    cheers,
    Martin
     
    Wednesday, June 23, 2010 8:17 AM
  • Martin Ba. wrote:

    C++ DLL interfaces are neccessarily incompatible across compiler
    versions and switches.
    That does not mean it's a bad idea to use exported C++ interfaces - it
    just means you can only use them when you compile everything together.
    (Like when you split some modules of an app into DLLs.)

    So, why would you want to split some modules into DLLs? What benefit  do you expect to derive from that? The typical answer - "so they could  be independently maintained" - doesn't fly here, because of "compile  everything together" requirement.


    Igor Tandetnik

    Wednesday, June 23, 2010 12:10 PM
  • Igor Tandetnik wrote:
    > Martin Ba. wrote:
    >
    > C++ DLL interfaces are neccessarily incompatible across compiler
    > versions and switches.
    > That does not mean it's a bad idea to use exported C++ interfaces - it
    > just means you can only use them when you compile everything together.
    > (Like when you split some modules of an app into DLLs.)
    >
    > So, _why_ would you want to split some modules into DLLs? What benefit
    > do you expect to derive from that? The typical answer - "so they could
    > be independently maintained" - doesn't fly here, because of "compile
    > everything together" requirement.
    >
     
    If the compiler settings are correctly maintained in source control then
    it would still be possible to compile it separately.
     
    I would split them up because the application consists of 4 different
    executables and common modules are implemented as DLLs that are used by
    all/some of these executables.
     
    br,
    Martin
     
    Thursday, June 24, 2010 6:23 AM