You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 09:37:09