【问题标题】:OleVariant and String assignments in Delphi 5Delphi 5 中的 OleVariant 和字符串赋值
【发布时间】:2012-03-06 20:46:27
【问题描述】:

我有一个 Delphi 5 遗留应用程序,其中有一个“字符串”值被分配给“OleVariant”变量的部分。像这样的:

var
   X: OleVariant;
   S: string;
Begin
   S:= ‘This string should contain 200 characters as per design’;
   X:= S; 
End;

如果“S”的长度大于 128,则“X”的值会被截断,最多只能保存 128 个字符。

有没有办法克服这个问题?

我相信有一种方法,因为如果我从头开始创建自己的演示应用程序(在同一台 PC 上,使用相同的 Delphi 5),它允许我传递更长的字符串值并且不会进行截断。

可能与项目设置或编译器指令有关。我已经尝试过这个想法,但我还没有解决方法。

感谢任何帮助。谢谢。

演示:

procedure TForm1.Button1Click(Sender: TObject);
var
  X: OleVariant;
  S: string;
begin
  //in the Edit I pass a string of 240 chars, let's say;
  S:= Edit1.Text;
  X:= S;
  ShowMessage(IntToStr(Length(X)) + ' : ' + IntToStr(Length(S)));
  //this showmessage shows "128 : 240"
end;

【问题讨论】:

  • 请复制并粘贴真实代码,以证明您声明的内容。我期望一些代码分配一个 实际 200 个字符长的string 变量,以及一些测量OleVariant 值的长度并打印值128 的代码。如果这不是您确定存在问题的方式,那么请描述您所做的 以得出X 的长度仅为128 个字符的结论。
  • 看描述。我添加了更多代码。如果您调试和跟踪应用程序(调试时检查 X 和 S),您也可以注意到问题。
  • 我在 Delphi 4 (Windows 95) 中试过这个,字符串被 not 截断。
  • 用 D5 测试。工作正常。唯一会影响字符串长度的是使用{$H-}{$LONGSTRINGS OFF},但这将截断为255 (ShortString)。确保没有其他单位重新定义OleVariant,例如type OleVariant = string[128]。将'X'定义为X: System.OleVariant并再次测试...... HTH
  • @kobik type OleVariant = string[128]。那会很恶心!! ;-) 一个狡猾的头脑。

标签: string delphi delphi-5


【解决方案1】:

http://www.foxbase.ru/delphi/vzaimnye-preobrazovaniya-olevariant-i-string.htm

试试这个 OleVariantToStringStringToOleVariant 函数

它们非常适合我。

uses Classes, Variants;
function OleVariantToString(const Value: OleVariant): string;
  var ss: TStringStream;
      Size: integer;
      Data: PByteArray;
begin
  Result:='';
  if Length(Value) = 0 then Exit;
  ss:=TStringStream.Create;
  try
    Size := VarArrayHighBound (Value, 1) - VarArrayLowBound(Value, 1) + 1;
    Data := VarArrayLock(Value);
    try
      ss.Position := 0;
      ss.WriteBuffer(Data^, Size);
      ss.Position := 0;
      Result:=ss.DataString;
    finally
      VarArrayUnlock(Value);
    end;
  finally
    ss.Free;
  end;
end;

function StringToOleVariant(const Value: string): OleVariant;
  var Data: PByteArray;
      ss: TStringStream;
begin
  Result:=null;
  if Value='' then Exit;
  ss:=TStringStream.Create(Value);
  try
    Result := VarArrayCreate ([0, ss.Size - 1], varByte);
    Data := VarArrayLock(Result);
    try
      ss.Position := 0;
      ss.ReadBuffer(Data^, ss.Size);
    finally
      VarArrayUnlock(Result);
    end;
  finally
    ss.Free;
  end;
end;

【讨论】:

    【解决方案2】:

    一种解释是OleVariant 包含整个字符串,但您正在查看调试器工具提示。在较旧的 Delphi 版本中,调试器工具提示会在变体中保存的字符串中截断 128 个字符。请注意,普通string 的调试器工具提示不会在此长度处截断。尝试在对话框中显示变体,您会看到整个字符串都存在。

    我在 Delphi 6 上检查了这一点,您的代码没有截断(调试器工具提示除外)。 Andreas 在 Delphi 4 上也是如此,Rodrigo 在 Delphi 5 上也是如此。我无法想象 Delphi 5 OleVariant 中的字符串会被截断为 128 个字符。

    如果你真的看到你报告的内容,那么我可以想到以下解释:

    • 您的代码错误地截断了字符串,但您尚未找到执行此操作的代码。只有你可以调试它。
    • 您的 Delphi 安装有一个本地错误。您是否有机会编译自己的 RTL?

    【讨论】:

    • 这不是“变体”,而是“OleVariant”。我确实使用了一条显示消息,但它仍然被截断。注意:在我的案例中,“变体”工作得很好;尽管如此,“OleVariant”还是失败了。
    • 我在 D6 试验中使用 OleVariant
    • 各位,谢谢你们的帮助。我不能透露我的遗留应用程序的代码(因为它不属于我)。此外,它包含超过一百万行代码。
    • 这不是小事:它不是调试器(我可以向你保证);我什至可以将 OleVariant 变量转储到文本文件中,并且内容仍然被截断。所以,它不是调试器。
    【解决方案3】:

    我完成了这项工作。摘要:而不是用“字符串”填充“OleVariant”;我填写了一个“Variant”,然后将该“Variant”类型转换为“OleVariant”。看看下面的代码,你就能明白了。

    procedure TForm1.Button1Click(Sender: TObject);
    var
      //X: OleVariant;
      X: Variant;
      S: string;
    begin
      //Let's say in the Edit1 I pass a string of 240 chars,
      S:= Edit1.Text;
      X:= S;
    
      //ShowMessage(IntToStr(Length(X)) + ' : ' + IntToStr(Length(S)));
      ShowMessage(IntToStr(Length(OleVariant(X))) + ' : ' + IntToStr(Length(S)));
      //This ShowMessage shows "128 : 240"
    end;
    

    老实说,我不确定为什么这会有所作为,但确实如此。现在可以正常使用了。

    非常感谢您的帮助!

    【讨论】:

    • 这是因为将字符串转换为OleVariant 会将其转换为WideString(COM 兼容)。您的一个单元可能与 oleaut32 Sysxxx 函数之一(可能在初始化部分)发生了冲突,或者您有一个自定义内存管理器。
    猜你喜欢
    • 2010-12-18
    • 1970-01-01
    • 2011-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多