"David Wilkinson" wrote:
Terry Steyaert wrote:
I have a third party DLL (lib, includes, dll, no source) that references
CString in both return codes and function arguments. At link time, I receive
errors because the declaration of CString has changed.
There is no way I can change the DLL, so my only idea is that I need to
create a temporary VC++ 6.0 CString. My error lists the VC++ 2008 CString
definition (since it isn't found in the DLL) but I can't think of a way to
get the VC++ 6.0 revision of CString.
For example, from the include, I have:
CString GetLastError();
Which is causing a link error:
App_FSI_Comm.obj : error LNK2028: unresolved token (0A000901) "public: class
ATL::CStringT<char,class StrTraitMFC_DLL<char,class ATL::ChTraitsCRT<char> >
__thiscall CSabreComm::GetLastError(void)"
(?GetLastError@CSabreComm@@$$FQAE?AV?$CStringT@DV?$StrTraitMFC_DLL@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@XZ)
referenced in function __catch$?UpdateFlightList@CApp_FSI_Comm@@$$FIAE_N_N@Z$0
I found:
http://social.microsoft.com/Forums/en-US/vcgeneral/thread/ade8cf7a-b1e1-4853-ac37-d4b48a0b90ae
but short of making another DLL (which I'm not sure would function since
I'll still have the link errors), the solutions didn't work.
Any ideas greatly appreciated. Intuiting the VC++ 6.0 CString would
probably be the best.
Terry:
The moral of this story is to never ever use 3rd party DLL's unless either
1. You have source code
2. The DLL is a COM DLL, or is otherwise carefully designed to use a
compiler-independent interface.
As it is, you will either have to stick with VC6 for your whole application, or
use VC6 to wrap the existing DLL functionality in another DLL which has a
compiler-independent interface.
--
David Wilkinson
Visual C++ MVP
While I agree with your answer, you really should try living in the real
world. First off, we are all dependent on Microsoft DLLs, and we definitely
NEVER get source code for them. If you want to add a grid, Rogue Wave offers
a nice add-on called Objective Grid.
I've also done work for the big three and used DLLs by GM and Ford. Again,
no chance for source code. I've done work for airlines and had various DLLs
provided.
Now, we may get an updated DLL, but it has taken a very long time. We
"fixed" our problem with Objective Grid with a new version, so the DLL uses
the current CString definition.
Personally, a DLL is a great way to work, but the interfaces should be as
base as you can make, so rather than returning a CString, return an LPCSTR or
char*. As long as the compiler supports standard strings, that should
compile successfully.
I'm hoping that someone knows how to determine was a VC++ 6.0 CString's
"standard" template definition is. I'd hope VC++ 2008 can convert from that
template definition to the current CString. (I change the include file from
"CString" to class ATL::CStringT<char,class StrTraitMFC_DLL<char,class
ATL::ChTraitsCRT<char> >, so the DLL will link. On the actual return, it
should be able to convert the template back to a standard CString.
I do realize that I could probably build a VC++ 6.0 DLL that will convert
the CString to an LPCSTR and return, and convert the function with the
incoming parameters the same way, but it really seems like we should be able
to accomplish this, since the real problem in this case is Microsoft's change
of the CString template.
So, while I agree with your sentiment, many people in the real world need to
work with third party DLLs. If you want to work with GM, you probably need
to interface with FLEX via a GM/EDS DLL. If you want to work with American,
you probably need to interface with Sabre. If you want to work with Boeing,
you probably need to interface with something from them. If you want to run
in Windows, you must rely on Microsoft. If you want to run on Mac, you need
to rely on Apple.
Unless you build self-supporting code, odds are you are relying on something
that you don't have source code.
they are updated (by Microsoft) for each new version of the compiler.
And if you are working "with" a third party, rather than using them as a vendor,
I don't know why they would not be providing updated versions of their DLL's. Or
require you to use VC6, if that is what they do.
and typedef to perform its 8-bit/16-bit magic. But it is not just a matter of
the layout of the CString class. Typical cross-module uses of CString require
allocating memory in one module and releasing it in another; this will not work
if the modules are using different heaps.
Personally, I would go with the wrapper DLL method. Wrapping, like unit testing,
in your code. Hopefully this will help you next time to write clean interfaces
from the beginning.