Delphi 6迁移至2009时TdxDBGrid空字符串转Double报错求助
Delphi 6 → Delphi 2009迁移:TdxDBGrid空字符串转Double报错的修正方案咨询
我正在将基于TdxDBGrid的Delphi 6应用迁移至Delphi 2009,现阶段计划继续使用TdxDBGrid(后续会逐步迁移到TcxGrid,因TcxGrid暂缺部分必需功能)。但用户通过TdxDBGrid输入新行及数值时,触发如下错误:
Could not convert variant of type (UnicodeString) into type (Double)
问题根源分析
经代码追踪,问题源于空字符串''转换为Double类型的逻辑差异,涉及Delphi 6与2009的RTL中Variants.pas的相关函数实现不同。
Delphi 2009的VarToDoubleAsString函数
function VarToDoubleAsString(const V: TVarData): Double; var S: WideString; LValue: Extended; LResult: HResult; begin _VarToWStr(S, V); LResult := VarR8FromStr(S, VAR_LOCALE_USER_DEFAULT, 0, Result); case LResult of VAR_OK:; // 此时系统函数已将值写入Result VAR_TYPEMISMATCH: if TryStrToFloat(S, LValue) then Result := LValue else VarResultCheck(VAR_TYPEMISMATCH, V.VType, varDouble); else VarResultCheck(LResult, V.VType, varDouble); end; end;
Delphi 6的VarToRealAsString函数
function VarToRealAsString(const V: TVarData): Extended; var S: String; LValue: Double; LResult: HResult; begin _VarToLStr(S, V); LResult := VarR8FromStr(S, $400, 0, LValue); if LResult = VAR_OK then Result := LValue else if not TryStrToFloat(S, Result) then VarResultCheck(LResult, varString, varDouble); end;
具体问题点
执行LResult := VarR8FromStr(S, VAR_LOCALE_USER_DEFAULT, 0, Result);时返回类型不匹配,流程进入TryStrToFloat(S, LValue)分支但转换失败。我无法理解TryStrToFloat('', very-small-number)为何会失败,查看相关转换函数:
function TryStrToFloat(const S: string; out Value: Extended): Boolean; begin Result := TextToFloat(PChar(S), Value, fvExtended); end;
可见TryStrToFloat期望接收UnicodeString,但此前处理均使用WideString,转换逻辑如下:
procedure _UStrFromWStr(var Dest: UnicodeString; const Source: WideString); asm { -> EAX pointer to dest } { EDX pointer to WideString data } XOR ECX,ECX TEST EDX,EDX JZ @@1 // 空源字符串 => 长度为0 MOV ECX,[EDX-4] SHR ECX,1 // WideString的长度是字节数,需转字符数 @@1: JMP _UStrFromPWCharLen end;
我推测可能的原因:
WideString类型的空字符串''无法正确转换为UnicodeString;- 默认值
very_small_number的设置不符合转换要求。
求助
我计划通过修改这些Variant处理函数,将修正后的Variants.pas加入项目,以暂时继续使用旧版TdxDBGrid。请问有没有开发者遇到过此类迁移问题,熟悉这类Variant处理/转换逻辑,能提供相对安全的修正方案?
内容的提问来源于stack exchange,提问作者TomR
相关产品推荐
相关产品推荐

