Linker error when calling legacy DLL methods with CString arguments

I am developing a C++ application in Visual Studio 2005 that needs to call methods in a legacy MFC DLL that exports a class with CString arguments in its public methods. The legacy DLL is compiled in Visual Studio 6 and I don't have the source files for it so I have to use it as it is.

My problem is that I cannot link with the DLL. When I call one of the methods having a CString argument I get this linker error:

error LNK2019: unresolved external symbol "__declspec(dllimport) public: static bool __cdecl DFUEngine::IsDFUFileValid(class ATL::CStringT<wchar_t,class StrTraitMFC_DLL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > > const &)" (__imp_ IsDFUFileValid@DFUEngine@@SA_NABV $CStringT@_WV StrTraitMFC_DLL@_WV $ChTraitsCRT@_W@ATL@@@@@ATL@@@Z) referenced in function "public: bool __thiscall DFUEngineWrapper::IsDFUFileValid(wchar_t const *)" ( IsDFUFileValid@DFUEngineWrapper@@QAE_NPB_W@Z) DFUEngineWrapper.obj


I have searched the Internet for solutions and it seems to be a well-known problem caused by the fact that Microsoft has changed CString from being a class to a template (CStringT) since VS 6.

Most solutions suggests recompiling the DLL with VS2005, but my problem is that I don't have the source files for the DLL. So what can I do Is there a way I can force VS 2005 to use the old-style (VS 6) CString type

Thanks
Bo



Answer this question

Linker error when calling legacy DLL methods with CString arguments

  • skatterbrainz

    Maybe the following works:

    Project ->Properties->Configuration Properties-> General->Common Language Runtime support:

    Select the last one, Common Language Runtimesupport, old syntax()...


  • adamwendt

    Thank you for your suggestions. I have tried them all, but without luck.

    The method I am calling has this signature:

    static bool IsDFUFileValid(const CString &name);

    Is the cause of my linker problem that it is a CString reference argument, and not just a CString passed by value

    I tried to recompile my project without using Unicode - didn't help.

    I tried calling the method with a char* argument - didn't help.

    Next thing I will try is to write a wrapper DLL using Visual Studio 6.0 that encapsulates my legacy DLL and exposes the same public methods, but with all CString arguments replaced by LPSTR arguments.

    Best regards

    Bo


  • margemoosh

    Yes, I have run into this error, in a much simpler situation: (I am using vs2003)
    Make a non-MFC dll that exports a CString parmatered-member function
    Make a MFC 'test app' that imports same.
    Magically, you get the same kind of error: cannot find __functioname__ CStringMFC xxxyyyzzz

    ..and if you use 'depends' on the DLL that exports this member, you will get a mangled name like:__functioname__ ATL::CStringT xxxyyyzzz

    So, without MFC you have a TOTALLY DIFFERENT STRING TYPE. Your link error is due to you publishing one thing, but the app is looking for something different. The one string is defined in afxstr.h (MFC) the other in atlstr.h. Just for fun, try to 'include' afxstr.h in your project, you will find it complaining that your project is NOT mfc...

    Also, try adding this into you project somewhere:

    void test()
    {
    StrTraitATL< char, ChTraitsOS< char > >::GetDefaultManager();
    StrTraitMFC< char, ATL::ChTraitsCRT< char > >::GetDefaultManager();
    }


    In my case, changing the DLL to use LPCSTR worked, since I was able to re-export and rebuild the DLL.

    Your case, maybe if you made a separte 'adapter' DLL that uses MFC, imports the 'existing' dll, and converts the parameters to CHAR* or something compatible.

    Sucks, doesn't it Makes you wish you used std::string


    K

  • Bjorn Erik

    It may be that the DLL you are linking to is looking for and ANSI rather than Unicode CString. Try changing your project to not use Unicode. (Hopefully this is a viable option for you).

  • DrRickS

    Also, if this doesn't work, you can always link against the 6.0 ATLMFC libraries (ATLMFC 4.2 I think) which should be installed with VS 6.0.

    This is probably not the greatest idea since it would mean you'd be reverting ATLMFC by several versions, so if there's any possible way you can get an update to your DLL you may want to persue that.



  • Intec

    Also, try passing in char*'s instead of CStrings to see if it will automatically convert for you (I believe it should).

  • ASTECH

    Your last suggestion is a good one. You could also start linking against the 6.0 libs from your 2005 project. Really, really though it's much better to get the old libs recompiled somehow or simply toss them out.

  • Damien Sauveron

    Hi,

    Strangely I have no problem what so ever. I just tried it and it works fine. Can you show the declaration of the legacy function here

    Anyway as possible solution I would sugest you, is not to link with the dll statically, but to use LoadLibrary.

    Max



  • Linker error when calling legacy DLL methods with CString arguments