-
September 13th, 2013, 07:24 AM
#1
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
-
September 13th, 2013, 07:48 AM
#2
Re: CString class in non-MFC static library
Originally Posted by AnotherMuggle
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?
-
September 13th, 2013, 08:15 AM
#3
Re: CString class in non-MFC static library
Originally Posted by GCDEF
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
-
September 13th, 2013, 09:56 AM
#4
Re: CString class in non-MFC static library
Originally Posted by AnotherMuggle
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
-
September 13th, 2013, 10:07 AM
#5
Re: CString class in non-MFC static library
Originally Posted by Paul McKenzie
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.
-
September 13th, 2013, 10:14 AM
#6
Re: CString class in non-MFC static library
Originally Posted by AnotherMuggle
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
-
September 13th, 2013, 10:32 AM
#7
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...
-
September 13th, 2013, 10:46 AM
#8
Re: CString class in non-MFC static library
Originally Posted by ovidiucucu
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
-
September 13th, 2013, 11:20 AM
#9
Re: CString class in non-MFC static library
MFC + ATL + STL = (much more) HEADACHES.
Originally Posted by AnotherMuggle
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.
-
September 16th, 2013, 08:15 AM
#10
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.
-
September 16th, 2013, 08:24 AM
#11
Re: CString class in non-MFC static library
Originally Posted by OReubens
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.
-
September 17th, 2013, 06:49 AM
#12
Re: CString class in non-MFC static library
Originally Posted by AnotherMuggle
Hi OReubens, I followed ovidiucucu's advice and it works perfectly, thanks.
maybe... but you asked for.
Originally Posted by AnotherMuggle
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.
-
November 13th, 2015, 12:00 PM
#13
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
-
November 13th, 2015, 02:12 PM
#14
Re: CString class in non-MFC static library
Originally Posted by Prandr
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.
-
November 13th, 2015, 02:48 PM
#15
Re: CString class in non-MFC static library
Originally Posted by tiliavirga
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.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|