VS2008 WIN32升级VS2017 X64
工程配置修改
-
用vs2017打开原vs2008的工程,自动升级工程。
-
修改所有Project的Windows SDK Version(默认升级完会变成8.1,但是VS2017自带的是10.x.x)
- 新增X64平台配置。
- 覆盖提供的tq_lib目录,修改MsgServer和NpcServer工程的库包含路径:
mysql->mysql64 lib->lib_X64 GameLib->GameLib_X64
- 覆盖提供的游服运行环境(X64运行环境DLL.rar)到游服运行环境目录sjmy_server_bin。(请注意备份原来的运行环境,建议新建一个sjmy_server_bin_X64来运行X64的游服)。
源码修改
- hash_map已废弃,需修改为unordered_map:
#ifdef USE_SGISTL
typedef std::hash_map<const char*, CMemberInfo*, std::hash<const char*>, tqstd::str_equal> STR_INDEX;
#else
typedef stdext::hash_map<const char*, CMemberInfo*, stdext::hash_compare<char const *,tqstd::str_less> > STR_INDEX;
需要修改为:
typedef std::unordered_map<const char*, CMemberInfo* > STR_INDEX;
不过这里需要注意的是,unordered_map对于const char*类型,只会对指针进行hash和值比较,并不会比较字符串内容,如果需要支持字符串比较,需要自行特化模板类hash和equal_to:
// 特例化字串比较,用于unordered_map
namespace std
{
template<> struct equal_to<const char*>
{
bool operator()(const char* lhs, const char* rhs) const
{
return strcmp(lhs, rhs) == 0;
}
};
template<> struct hash<const char*>
{
size_t operator()(const char* str) const
{
char *src = (char*)str;
unsigned int seed = 131; // 31 131 1313 13131 131313 etc..
unsigned int hash = 0;
while (*src)
{
hash = hash * seed + (*srcpp);
}
return (hash & 0x7FFFFFFF);
}
};
}
也可以用宏强制启用hash_map:
#define _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS
-
外部库需要使用VS2017 x64重新编译,否则链接时会提示unresolved external symbol.
-
字符串拼接问题。常量字符串拼接,原来可以写成:
PARAMBUF szFuncLine; sprintf( szFuncLine, LUA_FUNC_NAME"%s"LUA_PARAM_NUMB"%d", szFuncName, nParam0 );
VS2017中,常量字符串和用双引号包围的字符串之间拼接,必须使用空格隔开,否则编译无法通过:
PARAMBUF szFuncLine;
sprintf( szFuncLine, LUA_FUNC_NAME"%s" LUA_PARAM_NUMB"%d", szFuncName, nParam0 );
-
VS2017可以检查出格式化字符串(如sprintf,sscanf等)中格式化符号和参数的数量和类型是否匹配,编译时会给出一个warnning,编码时请注意查看。
warning C4477: 'sprintf' : format string '%u' requires an argument of type 'unsigned int', but variadic argument 5 has type 'time_t' note: consider using '%llu' in the format string note: consider using '%Iu' in the format string note: consider using '%I64u' in the format string
-
升级X64以后,size_t和time_t的长度由4字节变成了8字节,使用int或者DWORD来接收size_t和time_t的参数,可能发生截断,使用时需要注意截断后是否可能产生错误。另外,不要在消息协议中使用size_t和time_t,可能导致客户端解析消息协议不正确!!
编译选项
-
解决重复定义问题:linker->Command Line加上
/FORCE:MULTIPLE
-
VS2017可以正常生成超大的.lib,不再需要制定预计输出大小:
/expectedoutputsize:2400000000