#7254 closed defect (fixed)
CPLString makes gdal.dll export symbols for std::string on MSVS 2010-2017
Reported by: | opals | Owned by: | warmerdam |
---|---|---|---|
Priority: | normal | Milestone: | 2.3.0 |
Component: | default | Version: | 2.2.3 |
Severity: | normal | Keywords: | CPLString multiply defined symbols STL |
Cc: |
Description
Because CPLString derives from std::string, gdal.dll created with MSVC (tested on MSVS 2010 and MSVS 2017) exports symbols not only for CPLString, but also for std::string. This becomes a problem when linking both GDAL and a static library that (implicitly) instantiates std::string (many will do that!). The work-around to force the linker to still generate its output is a generally unsafe option. Much better is to make CPLString not export symbols for std::string. This relates to the same problem as defect #4099 However, in #4099, we suggested to either
- not export symbols for CPLString at all, which forces binaries that need to use CPLString (like the GDAL utility programs) to link GDAL statically, or
- not derive CPLString from std::string, but make std::string a member variable hidden in a D-Pointer (pimpl-idiom).
Contrary to the 2 options suggested in #4099, we now use a much less intrusive solution: For MSVC, turn the declaration of CPLString into the declaration of the template class CPLStringT, and make CPLString itself a typedef of that template class. Do not export symbols for the template class as a whole, but only for its few non-inline member functions. Hence, no symbols for std::string are exported, and no symbols for the inline member functions of CPLString. Still, all methods of CPLString and its base class std::string remain available, since they are implicitly instantiated (instead of explicitly, like currently), thereby avoiding duplicate symbols. Resolution attached, based on GDAL 2.2.3. Possibly, also port/cpl_port.h needs to be extended slightly, such that CPL_DLL is defined as declspec(dllimport) when symbols are to be imported by MSVC:
#ifndef CPL_DLL #if defined(_MSC_VER) && !defined(CPL_DISABLE_DLL) # ifdef GDAL_EXPORTS # define CPL_DLL declspec(dllexport) # else # define CPL_DLL declspec(dllimport) # endif #else ... #endif
Attachments (3)
Change History (7)
by , 6 years ago
Attachment: | cpl_port.h added |
---|
comment:1 by , 6 years ago
@opals Can you propose your changes as a pull request against https://github.com/OSGeo/gdal so that it is easier to review them ?
comment:4 by , 6 years ago
Milestone: | → 2.3.0 |
---|
I considered to backport this for 2.2.4 as well, but it looks like it would change the ABI, so I decided not.
cpl_port.h Based on GDAL 2.2.3