今天用vs2019编译一个在vs2008下coding的工程的时候,vs给出了一堆链接错误信息,如下图所示的一些错误:
error 47 error lnk2019: unresolved external symbol "public: __thiscall std::_mutex::~_mutex(void)" (??1_mutex@std@@qae@xz) referenced in function "public: void __thiscall std::ios_base::clear(int,bool)" (?clear@ios_base@std@@qaexh_n@z) d:\server\mysqlpp.lib(dbdriver.obj) server
error 48 error lnk2001: unresolved external symbol "public: __thiscall std::_mutex::~_mutex(void)" (??1_mutex@std@@qae@xz) d:\server\mysqlpp.lib(datetime.obj) server
error 49 error lnk2001: unresolved external symbol "public: __thiscall std::_mutex::~_mutex(void)" (??1_mutex@std@@qae@xz) d:\server\mysqlpp.lib(stadapter.obj) server
error 50 error lnk2001: unresolved external symbol "public: __thiscall std::_mutex::~_mutex(void)" (??1_mutex@std@@qae@xz) d:\server\mysqlpp.lib(sqlstream.obj) server
error 51 error lnk2001: unresolved external symbol "public: __thiscall std::_mutex::~_mutex(void)" (??1_mutex@std@@qae@xz) d:\server\mysqlpp.lib(connection.obj) server
error 52 error lnk2001: unresolved external symbol "public: __thiscall std::_mutex::~_mutex(void)" (??1_mutex@std@@qae@xz) d:\server\mysqlpp.lib(mystring.obj) server
error 53 error lnk2001: unresolved external symbol "public: __thiscall std::_mutex::~_mutex(void)" (??1_mutex@std@@qae@xz) d:\server\mysqlpp.lib(row.obj) server
error 54 error lnk2001: unresolved external symbol "public: __thiscall std::_mutex::~_mutex(void)" (??1_mutex@std@@qae@xz) d:\server\mysqlpp.lib(query.obj) server
error 55 error lnk2001: unresolved external symbol "long const std::_badoff" (?_badoff@std@@3jb) d:\server\mysqlpp.lib(dbdriver.obj) server
error 56 error lnk2001: unresolved external symbol "long const std::_badoff" (?_badoff@std@@3jb) d:\server\mysqlpp.lib(datetime.obj) server
error 57 error lnk2001: unresolved external symbol "long const std::_badoff" (?_badoff@std@@3jb) d:\server\mysqlpp.lib(stadapter.obj) server
error 58 error lnk2001: unresolved external symbol "long const std::_badoff" (?_badoff@std@@3jb) d:\server\mysqlpp.lib(sqlstream.obj) server
error 59 error lnk2001: unresolved external symbol "long const std::_badoff" (?_badoff@std@@3jb) d:\server\mysqlpp.lib(connection.obj) server
error 60 error lnk2001: unresolved external symbol "long const std::_badoff" (?_badoff@std@@3jb) d:\server\mysqlpp.lib(mystring.obj) server
error 61 error lnk2001: unresolved external symbol "long const std::_badoff" (?_badoff@std@@3jb) d:\server\mysqlpp.lib(row.obj) server
error 62 error lnk2001: unresolved external symbol "long const std::_badoff" (?_badoff@std@@3jb) d:\server\mysqlpp.lib(query.obj) server
error 63 error lnk2001: unresolved external symbol "public: static void __cdecl std::_string_base::_xran(void)" (?_xran@_string_base@std@@saxxz) d:\server\mysqlpp.lib(qparms.obj) server
error 64 error lnk2001: unresolved external symbol "public: static void __cdecl std::_string_base::_xran(void)" (?_xran@_string_base@std@@saxxz) d:\server\mysqlpp.lib(sqlstream.obj) server
error 65 error lnk2001: unresolved external symbol "public: static void __cdecl std::_string_base::_xran(void)" (?_xran@_string_base@std@@saxxz) d:\server\mysqlpp.lib(options.obj) server
error 66 error lnk2001: unresolved external symbol "public: static void __cdecl std::_string_base::_xran(void)" (?_xran@_string_base@std@@saxxz) d:\server\mysqlpp.lib(field_types.obj) server
error 67 error lnk2019: unresolved external symbol "public: static void __cdecl std::_string_base::_xran(void)" (?_xran@_string_base@std@@saxxz) referenced in function "public: char __thiscall mysqlpp::sqltypeadapter::at(unsigned int)const " (?at@sqltypeadapter@mysqlpp@@qbedi@z) d:\server\mysqlpp.lib(stadapter.obj) server
error 68 error lnk2001: unresolved external symbol "public: static void __cdecl std::_string_base::_xran(void)" (?_xran@_string_base@std@@saxxz) d:\server\mysqlpp.lib(manip.obj) server
error 69 error lnk2001: unresolved external symbol "public: static void __cdecl std::_string_base::_xran(void)" (?_xran@_string_base@std@@saxxz) d:\server\mysqlpp.lib(null.obj) server
error 70 error lnk2001: unresolved external symbol "public: static void __cdecl std::_string_base::_xran(void)" (?_xran@_string_base@std@@saxxz) d:\server\mysqlpp.lib(datetime.obj) server
error 71 error lnk2001: unresolved external symbol "public: static void __cdecl std::_string_base::_xran(void)" (?_xran@_string_base@std@@saxxz) d:\server\mysqlpp.lib(type_info.obj) server
error 72 error lnk2001: unresolved external symbol "public: static void __cdecl std::_string_base::_xran(void)" (?_xran@_string_base@std@@saxxz) d:\server\mysqlpp.lib(vallist.obj) server
error 73 error lnk2001: unresolved external symbol "public: static void __cdecl std::_string_base::_xran(void)" (?_xran@_string_base@std@@saxxz) d:\server\mysqlpp.lib(field_names.obj) server
error 74 error lnk2001: unresolved external symbol "public: static void __cdecl std::_string_base::_xran(void)" (?_xran@_string_base@std@@saxxz) d:\server\mysqlpp.lib(query.obj) server
error 75 error lnk2001: unresolved external symbol "public: static void __cdecl std::_string_base::_xran(void)" (?_xran@_string_base@std@@saxxz) d:\server\mysqlpp.lib(dbdriver.obj) server
error 76 error lnk2001: unresolved external symbol "public: static void __cdecl std::_string_base::_xran(void)" (?_xran@_string_base@std@@saxxz) d:\server\mysqlpp.lib(tcp_connection.obj) server
error 82 error lnk2001: unresolved external symbol "public: static void __cdecl std::_string_base::_xlen(void)" (?_xlen@_string_base@std@@saxxz) d:\server\mysqlpp.lib(null.obj) server
问题总结:
因为静态链接库mysqlpp.lib在旧版本ide上编译的,所以string类中符号被解析成形如 static void __cdecl _xran()或static void __cdecl _xlen()
而在高版本的vs2019上string中的_xran与_xlen符号则被解析成了__declspec(noreturn) void _xran() const或__declspec(noreturn) void _xlen() const
所以才会在链接过程中出现上述开头出现的一堆问题
#include <string>
namespace std2008
{
class _string_base_2008
{
public:
{
__declspec(dllexport) void _xlen2008(void) const;
__declspec(dllexport) void _xran2008(void) const;
};
};
void std2008::_string_base_2008::_xran2008 () const
{
std::_string_base::_xran ();
}
void std2008::_string_base_2008::_xlen2008 () const
{
std::_string_base::_xlen ();
}
save this code as "compat.cpp" and compile with
cl /d_dll_export /ehsc /ld compat.cpp /link
now lets examine the lib file, that has been created:
dumpbin /exports compat.lib
in my case it looks like this:
dump of file compat.lib
file type: library
exports
ordinal name
?_xlen2008@_string_base_2008@std2008@@qbexxz (public: void __thiscall std2008::_string_base_2008::_xlen2008(void)const )
?_xran2008@_string_base_2008@std2008@@qbexxz (public: void __thiscall std2008::_string_base_2008::_xran2008(void)const )
when looking at the linker errors about missing symbols, you see the decoration that is required. in your case its "?_xran@_string_base@std@@saxxz" and "?_xlen@_string_base@std@@saxxz"
the last step is to tell the linker to create a library that maps the standard decorated names to a another name using the symbols from your linker error and the names taken from dumpbin.
cl /ehsc /ld compat.cpp /link /export:?_xran@_string_base@std@@saxxz=?_xran2008@_string_base_2008@std2008@@qbexxz /export:?_xlen@_string_base@std@@saxxz=?_xlen2008@_string_base_2008@std2008@@qbexxz
cl /ehsc /ld compat1.cpp /link /export:??0exception@std@@qae@abqbd@z=??exception_2008@std2008@@qaexabqbd@z
now add the "compat.lib" library as additional library to your project and now it should link successfully.
compact.c代码
#include <string>
namespace std2008
{
class _string_base_2008
{
public:
__declspec(dllexport) void _xlen2008(void) const;
__declspec(dllexport) void _xran2008(void) const;
};
};
void std2008::_string_base_2008::_xran2008 () const
{
std::_string_base::_xran ();
}
void std2008::_string_base_2008::_xlen2008 () const
{
std::_string_base::_xlen ();
}
生成dll和lib
cl /d_dll_export /ehsc /ld compat.cpp /link
生成可用的lib
cl /ehsc /ld compat.cpp /link /export:?_xran@_string_base@std@@saxxz=?_xran2008@_string_base_2008@std2008@@qbexxz /export:?_xlen@_string_base@std@@saxxz=?_xlen2008@_string_base_2008@std2008@@qbexxz
compact1.c代码
#include <string>
namespace std2008
{
class exception_2008
{
public:
__declspec(dllexport) exception_2008(char const * const & ch);
};
};
std2008::exception_2008::exception_2008(char const * const & ch)
{
std::exception::exception (ch);
}
生成dll和lib
cl /d_dll_export /ehsc /ld compat1.cpp /link
生成可用的lib
cl /ehsc /ld compat1.cpp /link /export:??0
exception@std@@qae@abqbd@z=??exception_2008@std2008@@qaexabqbd@z
将生成的compat.dll和compat1.dll拷贝至exe目录,compat.lib和compat1.lib则拷贝至源文件与mysqlpp.lib同一目录中,即可顺利编译了!!
发表评论