VS2008 WIN32升级VS2017 X64

笔记 Apr 2, 2023

工程配置修改

  1. 用vs2017打开原vs2008的工程,自动升级工程。

  2. 修改所有Project的Windows SDK Version(默认升级完会变成8.1,但是VS2017自带的是10.x.x)

  1. 新增X64平台配置。

  1. 覆盖提供的tq_lib目录,修改MsgServer和NpcServer工程的库包含路径:

mysql->mysql64 lib->lib_X64 GameLib->GameLib_X64

  1. 覆盖提供的游服运行环境(X64运行环境DLL.rar)到游服运行环境目录sjmy_server_bin。(请注意备份原来的运行环境,建议新建一个sjmy_server_bin_X64来运行X64的游服)。

源码修改

  1. 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 
  1. 外部库需要使用VS2017 x64重新编译,否则链接时会提示unresolved external symbol.

  2. 字符串拼接问题。常量字符串拼接,原来可以写成:

    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 ); 
  1. 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

  2. 升级X64以后,size_t和time_t的长度由4字节变成了8字节,使用int或者DWORD来接收size_t和time_t的参数,可能发生截断,使用时需要注意截断后是否可能产生错误。另外,不要在消息协议中使用size_t和time_t,可能导致客户端解析消息协议不正确!!

编译选项

  1. 解决重复定义问题:linker->Command Line加上

    /FORCE:MULTIPLE 
    
  2. VS2017可以正常生成超大的.lib,不再需要制定预计输出大小:

   /expectedoutputsize:2400000000 

标签