CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 23
  1. #1
    Join Date
    May 2006
    Location
    England
    Posts
    72

    CString class in non-MFC static library

    Hi All,

    I have a non-MFC static library which I share between a number of different projects, some non-MFC and some MFC. Currently the static library uses a typedef of std::wstring and std::string for UNICODE and non-UNICODE builds.

    After discovering it's possible to use CString in non-MFC applications, by including atlstr.h header, I decided I'd rather that than using stl strings and having to keep converting between the different types. However, I seem to be struggling with linker errors when linking the library with a MFC application.

    Does anyone know if this is possible? Can I create a non-MFC static library using CString from atlstr.h and link it with a MFC application?

    Thanks in advance,
    AnotherMuggle.
    Last edited by AnotherMuggle; September 13th, 2013 at 07:42 AM. Reason: typo

  2. #2
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,635

    Re: CString class in non-MFC static library

    Quote Originally Posted by AnotherMuggle View Post
    Hi All,

    I have a non-MFC static library which I share between a number of different projects, some non-MFC and some MFC. Currently the static library uses a typedef of std::wstring and std::string for UNICODE and non-UNICODE builds.

    After discovering it's possible to use CString in non-MFC applications, by including atlstr.h header, I decided I'd rather that than using stl strings and having to keep converting between the different types. However, I seem to be struggling with linker errors when linking the library with a MFC application.

    Does anyone know if this is possible? Can I create a non-MFC static library using CString from atlstr.h and link it with a MFC application?

    Thanks in advance,
    AnotherMuggle.
    You think it may be useful to post what the errors are perhaps?

  3. #3
    Join Date
    May 2006
    Location
    England
    Posts
    72

    Re: CString class in non-MFC static library

    Quote Originally Posted by GCDEF View Post
    You think it may be useful to post what the errors are perhaps?
    DOH! Here are the errors:

    Code:
    Error    1    error LNK2019: unresolved external symbol "class ATL::CStringT<wchar_t,class StrTraitMFC_DLL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > > __cdecl System::GetRootDirectory(void)" (?GetRootDirectory@System@@YA?AV?$CStringT@_WV?$StrTraitMFC_DLL@_WV?$ChTraitsCRT@_W@ATL@@@@@ATL@@XZ) referenced in function "protected: virtual int __thiscall CMain::OnInitDialog(void)" (?OnInitDialog@CMain@@MAEHXZ)    <path_to_obj>.obj
    Error    2    error LNK1120: 1 unresolved externals    <path_to_dll>.dll

  4. #4
    Join Date
    Apr 1999
    Posts
    27,449

    Re: CString class in non-MFC static library

    Quote Originally Posted by AnotherMuggle View Post
    DOH! Here are the errors:
    If you read that error carefully, it isn't CString that has a problem. It is the function "System::GetRootDirectory" cannot be found. All that CString stuff at the beginning is just the expanded template name of CString.

    Regards,

    Paul McKenzie

  5. #5
    Join Date
    May 2006
    Location
    England
    Posts
    72

    Re: CString class in non-MFC static library

    Quote Originally Posted by Paul McKenzie View Post
    If you read that error carefully, it isn't CString that has a problem. It is the function "System::GetRootDirectory" cannot be found. All that CString stuff at the beginning is just the expanded template name of CString.

    Regards,

    Paul McKenzie
    Hi Paul,

    That function is the function I have converted from using a tstring (std::string/std::wstring) return type to a CString return type. If I change it back from CString to tstring the problem goes away. There are many more changes to be made but I just tested with this one function and immediately hit this problem.

    Cheers,
    AnotherMuggle
    Last edited by AnotherMuggle; September 13th, 2013 at 10:14 AM.

  6. #6
    Join Date
    Apr 1999
    Posts
    27,449

    Re: CString class in non-MFC static library

    Quote Originally Posted by AnotherMuggle View Post
    HI Paul,

    That function is the the function I have converted from using a tstring (std::string/std::wstring) return type to a CString return type. If I change it back from CString to tstring the problem goes away.
    The issue is still not a CString issue, given the linker error.

    The error means that the function (not the prototype, but the actual function) doesn't exist. That means that yes, you're calling the function with a CString return type and parameters, but nowhere in the object code does that actual function exist.

    In other words, no different than any other "linker can't find my function" error -- it's just a little more wordy due to the CString template (replace all that template stuff in the error message with "int" or "float" and you see what I mean).

    Regards,

    Paul McKenzie

  7. #7
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,234

    Re: CString class in non-MFC static library

    MFC + ATL = HEADACHE

    Well, now seriously:
    If press F12 on CString in an ATL project you will find:
    Code:
    // atlstr.h (ATL)
    typedef CStringT< TCHAR, StrTraitATL< TCHAR, ChTraitsCRT< TCHAR > > > CAtlString;
    // ...
    typedef CAtlString CString;
    while in an MFC one
    Code:
    // afxstr.h (MFC)
    typedef ATL::CStringT< TCHAR, StrTraitMFC_DLL< TCHAR > > CString;
    Pretty different and that's the reason you get that linker error.

    I don't know an easy workaround to get rid of that issue, other than the following: make the static library using MFC as well. As long as your application already uses MFC, then there is no additional overhead. And no more headaches...
    Ovidiu
    "When in Rome, do as Romans do."
    My latest articles: https://codexpertro.wordpress.com/

  8. #8
    Join Date
    May 2006
    Location
    England
    Posts
    72

    Re: CString class in non-MFC static library

    Quote Originally Posted by ovidiucucu View Post
    MFC + ATL = HEADACHE

    Well, now seriously:
    If press F12 on CString in an ATL project you will find:
    Code:
    // atlstr.h (ATL)
    typedef CStringT< TCHAR, StrTraitATL< TCHAR, ChTraitsCRT< TCHAR > > > CAtlString;
    // ...
    typedef CAtlString CString;
    while in an MFC one
    Code:
    // afxstr.h (MFC)
    typedef ATL::CStringT< TCHAR, StrTraitMFC_DLL< TCHAR > > CString;
    Pretty different and that's the reason you get that linker error.

    I don't know an easy workaround to get rid of that issue, other than the following: make the static library using MFC as well. As long as your application already uses MFC, then there is no additional overhead. And no more headaches...
    This seems to be the reason I'm having trouble and by the looks I am best leaving the static libary using STL, because I want to use it in both MFC and non-MFC applications, without having to change project settings each time I build. Setting the static library to use MFC causes errors when using the library with a non-MFC application.

    Thanks,
    AnotherMuggle

  9. #9
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,234

    Re: CString class in non-MFC static library

    MFC + ATL + STL = (much more) HEADACHES.

    Quote Originally Posted by AnotherMuggle View Post
    This seems to be the reason I'm having trouble and by the looks I am best leaving the static libary using STL, because I want to use it in both MFC and non-MFC applications, without having to change project settings each time I build. Setting the static library to use MFC causes errors when using the library with a non-MFC application.
    All you have to do with the static library is the following:
    • include <afx.h> instead of <atlstr.h>
    • set "Use MFC in a Shared DLL"
    • be sure Runtime Library is set to /MDd or /MD for DEBUG or RELEASE configuration, respectively;
    • enjoy...

    If you still want to make builds which do not use MFC, there is no necessary to modify each time the project settings. Just add a new configuration to the solution.
    Ovidiu
    "When in Rome, do as Romans do."
    My latest articles: https://codexpertro.wordpress.com/

  10. #10
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: CString class in non-MFC static library

    Just because ATL has a class that's called "CString" doesn't mean this is the exact same class as the one in MFC and that they're interchangable.

    you can use one from the other, but you're going to need to convert from one to the other in just the same way as you're doing now with std::string.

  11. #11
    Join Date
    May 2006
    Location
    England
    Posts
    72

    Re: CString class in non-MFC static library

    Quote Originally Posted by OReubens View Post
    Just because ATL has a class that's called "CString" doesn't mean this is the exact same class as the one in MFC and that they're interchangable.

    you can use one from the other, but you're going to need to convert from one to the other in just the same way as you're doing now with std::string.
    Hi OReubens, I followed ovidiucucu's advice and it works perfectly, thanks.

  12. #12
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: CString class in non-MFC static library

    Quote Originally Posted by AnotherMuggle View Post
    Hi OReubens, I followed ovidiucucu's advice and it works perfectly, thanks.
    maybe... but you asked for.

    Quote Originally Posted by AnotherMuggle View Post
    Can I create a non-MFC static library using CString from atlstr.h and link it with a MFC application?
    And then my point stands.


    If you're ok that your non-MFC static library is now a static library that requires the MFC DLL, then still "maybe". If and only if your exe also used MFC as a DLL.

    If your exe uses a static linked MFC, then it still won't work properly/relilably.

  13. #13
    Join Date
    Nov 2015
    Posts
    12

    Re: CString class in non-MFC static library

    I've had the same problem, I searched for it and found this thread.
    Now I write in this old thread because I feel I found an excellent solution, I want to share in case someone else will google for it and finds this thread.

    So simply add

    #ifdef _AFX
    #include <afxstr.h>
    #else
    #include <atlstr.h>
    #endif

    in front every class that uses CString,
    That way it willl use and link with MFC version of CString in MFC applications and ATL CString elsewhere. No more linker errors.

    Best regards

  14. #14
    Join Date
    Jun 2015
    Posts
    208

    Re: CString class in non-MFC static library

    Quote Originally Posted by Prandr View Post
    I found an excellent solution
    A much better solution is to always use standard C++ as much as possible.

    Only rely on third party libraries, like MFC and ATL, when you absolutely have to and then use them as little as you absolutely can.

    I know my suggestion comes too late for many who have already fallen into the honey trap and they may benefit from your suggestion of course.
    Last edited by tiliavirga; November 13th, 2015 at 02:28 PM.

  15. #15
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: CString class in non-MFC static library

    Quote Originally Posted by tiliavirga View Post
    A much better solution is to always use standard C++ as much as possible.

    Only rely on third party libraries, like MFC and ATL, when you absolutely have to and then use them as little as you absolutely can.

    I know my suggestion comes too late for many who have already fallen into the honey trap and they may benefit from your suggestion of course.
    I think if you are only targeting windows, then it's more convenient to use a string library that handles ANSI or UNICODE and provides methods that are useful when coding on Windows. Std string or wstring doesn't do this.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured