把 Mir2/传奇引擎的 DBServer 从 Delphi 2007(D2007)升级到 Delphi 10 以上(比如 Delphi 10.3/11.3),要注意很多地方,因为 D2009 开始 Delphi 就全面引入 UnicodeString,很多老游戏源码都会编译不过或出现逻辑错误。
我帮你整理一个升级要点清单,结合你之前遇到的 ShortString / Resume 等问题:
🔑 1. 字符串类型变化
- D2007 及以下:string = AnsiString,Char = AnsiChar,默认单字节。
- D2009 及以上:string = UnicodeString,Char = WideChar,默认双字节。
影响:
- 所有涉及 数据库字段、网络协议、文件存储 的地方必须保持字节兼容,否则会导致数据错位、存档损坏、客户端协议不兼容。
- 常见问题: sAccount: ShortString; / string[20] ← 隐式转换警告 PChar / PAnsiChar 混用 Length(s) 返回的长度单位是字符,不是字节
解决办法:
- 网络/存盘字段 → 保持 array of AnsiChar 或 ShortString,写入时用 StrLCopy / Move / PAnsiChar。
- 业务逻辑字符串 → 用 string,这样能享受 Unicode 支持。
🔑 2. API 调用参数变化
Windows API 在新 Delphi 里有两套:
- PChar 默认是 PWideChar(UTF-16)
- 老代码很多用 PAnsiChar
影响:
- MessageBox(PChar(...)) → 实际上传宽字符
- StrPas, StrPCopy 等 → 区分 Ansi 版和 Unicode 版
解决办法:
Application.MessageBox(PChar('提示'), '标题', MB_OK); // 宽字 Application.MessageBox(PAnsiChar(AnsiString('提示')), '标题', MB_OK); // 兼容旧逻辑

🔑 3. 线程控制
if not CreateSuspended then Resume;
- Delphi 2009+: Resume/Suspend 已过时 用 Start 启动线程
🔑 4. 记录结构体对齐
- 老 DBServer 很多 record 用 packed record,里头有 ShortString 或 array of Char,如果升级后不改,可能: SizeOf(record) 不一致 导致读写 DB 文件错位
建议:
- 用 packed record 明确对齐
- 对于存档/协议结构,建议改成 array of AnsiChar,不要用 string
🔑 5. 第三方控件 / 单元
- D2007 → D10,很多控件/单元名不同,例如: WinSock → Winapi.WinSock Windows → Winapi.Windows
- 一些 .dcu 没有源码,需要换成开源版本
🔑 6. 编译器警告
常见的警告:
- W1057:隐式转换 ShortString → string
- W1058:隐式转换 string → ShortString
- W1000:Resume/Suspend 已过时
建议:
- 涉及 DB/网络/存盘 → 手动处理转换
- 业务逻辑层 → 全部换 string/UnicodeString
🔑 7. SQL/ODBC/ADO 相关
如果 DBServer 里用 ADO / ODBC,要注意:
- TADOQuery 返回的是 WideString(自动 Unicode),可能和旧的 AnsiString 不兼容
- SQL 脚本里编码要改成 UTF-8/UTF-16
✅ 升级建议流程
- 先编译通过:遇到 W1057/W1058 警告,不要忽略,先全量记下来。
- 分类修改: 协议/存盘结构:保持 Ansi(array[0..xx] of AnsiChar) 普通业务逻辑:改用 string
- 跑通功能:重点测试 创建角色 登录 存档/读档 DB 转换工具
- 最后清理:把警告消除到最少,保证新版本维护无坑。
⚡ 总结:
- 最重要:区分 协议/存盘要 Ansi vs 业务逻辑可 Unicode。
- API 调用 → 明确 PAnsiChar 或 PWideChar。
- 线程 → 用 Start,不用 Resume。
结构体 → packed record + array of AnsiChar 最安全。
传奇 DBServer 的关键记录结构整理一个 Delphi 10+ 兼容版本,保证存档/协议不变形,同时解决你遇到的 W1057/W1058 警告。
以下是一个示例(结合你前面贴过的 TDBHeader、THumRecord.sAccount 等问题):
✅ 推荐改写(Delphi 10+ 兼容)
type // 数据库头结构 TDBHeader = packed record nVersion: Integer; nHumCount: Integer; nHumDataSize: Integer; // sDesc: ShortString; // ❌ 老写法 sDesc: array[0..63] of AnsiChar; // ✅ 固定 64 字节描述 end; // 人物数据结构 THumRecord = packed record // 账号 sAccount: array[0..19] of AnsiChar; // ✅ 固定 20 字节 // 人物名 sChrName: array[0..19] of AnsiChar; // ✅ 固定 20 字节 // 其他字段… nLevel: Integer; nJob: Byte; // ... end;
✅ 使用方法
写入字符串时,统一用 FillChar + StrLCopy,避免隐式转换:
// 写账号 FillChar(HumRecord.sAccount, SizeOf(HumRecord.sAccount), 0); StrLCopy(@HumRecord.sAccount[0], PAnsiChar(AnsiString(FrmCreateChr.sUserId)), SizeOf(HumRecord.sAccount) - 1); // 写描述 FillChar(NewDBHeader.sDesc, SizeOf(NewDBHeader.sDesc), 0); StrLCopy(@NewDBHeader.sDesc[0], PAnsiChar(AnsiString(sDBHeaderDesc)), SizeOf(NewDBHeader.sDesc) - 1);
这样:
- 不会再触发 W1058 警告
- 存盘文件和老版本保持完全一致(字节对齐没变)
- 同时避免了 string 隐式转换为 ShortString 的问题
✅ 总结
- 协议 / DB 文件用 array of AnsiChar,固定长度,字节对齐完全一致。
- 内部逻辑 / UI 用 string,不限制长度,支持 Unicode。
- 赋值时统一用 StrLCopy,避免 Delphi 自动转换。
具体参考:www.1234f.com
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删