CString class in non-MFC static library
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 12 of 12

Thread: CString class in non-MFC static library

  1. #1
    Join Date
    May 2006
    Location
    England
    Posts
    69

    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
    Posts
    12,132

    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
    69

    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,434

    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
    69

    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,434

    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
    ovidiucucu's Avatar
    ovidiucucu is offline Moderator/Reviewer Power Poster
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,051

    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 Cucu
    "When in Rome, do as Romans do."
    Visit: Microsoft Virtual Academy
    Follow: https://twitter.com/#!/ovidiucucu
    My blog: http://codexpert.ro/blog/author/ovidiu-cucu/

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

    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
    ovidiucucu's Avatar
    ovidiucucu is offline Moderator/Reviewer Power Poster
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,051

    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 Cucu
    "When in Rome, do as Romans do."
    Visit: Microsoft Virtual Academy
    Follow: https://twitter.com/#!/ovidiucucu
    My blog: http://codexpert.ro/blog/author/ovidiu-cucu/

  10. #10
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    3,997

    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
    69

    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
    3,997

    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.

Posting Permissions

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


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center