0

背景:将我的代码移植到 Delphi 10.1 Berlin 并通过第三方库工作。有些不再可用,所以我将尝试修复代码...

以下代码(将参数从程序的一个实例传递到另一个实例)引发对 StrLen 的 E2251 模糊重载调用。我明白为什么,我只是不知道解决它的最佳方法。

type
  PInstInfo = ^TInstInfo;
  TInstInfo = packed record
    FirstInstanceWnd:HWND;
    ParamCount:Integer;
    Params:Array[0..MAX_PARAMS-1, 0..MAX_PARAM_SIZE] of Char;
  end;

// Memory is filled with:
 lpInfo^.ParamCount:=ParamCount;
 if lpInfo^.ParamCount>MAX_PARAMS then
  lpInfo^.ParamCount:=MAX_PARAMS;
 for i:=0 to lpInfo^.ParamCount-1 do
 begin
  tempStr:=ParamStr(i+1);
  if length(tempStr)>MAX_PARAM_SIZE then
   setLength(tempStr,MAX_PARAM_SIZE);
  StrCopy(@(lpInfo^.Params[i,0]),PChar(tempStr));
 end;
 // and notify the first instance
 PostMessage(lpInfo^.FirstInstanceWnd, MSG_2ND_INSTANCE, 0, 0);



// And read using:
   if lpInfo <> nil then
   try
    // get Parameters
    params:=TStringList.Create;
    try
     for i:=0 to lpInfo^.ParamCount-1 do
     begin
      SetString(tempStr,
       PChar(@(lpInfo^.Params[i,0])),
       StrLen(@(lpInfo^.Params[i,0])));  <--- E2251 Ambiguious overloaded call to StrLen
      params.Add(tempStr);
     end;
     InstanceStarted(params);
    finally
     params.Free;
    end;

谢谢

4

1 回答 1

1

默认情况下,@地址运算符生成一个无类型指针。有两种重载版本StrLen(),一种采用 a PAnsiChar,另一种采用 a PWideChar。一个无类型的指针可以传递给这两个重载,从而产生歧义。PWideCharDelphi 2007 中不存在重载,这也是之前编译代码的原因。

要修复代码,您必须:

  1. 使用{$TYPEDADDRESS ON}or{$T+}编译器指令启用类型检查指针Char,因此使用运算符获取变量的地址@将生成类型化PChar指针而不是非类型化指针。

    {$TYPEDADDRESS ON}
    SetString(tempStr,
      @(lpInfo^.Params[i,0]),
      StrLen(@(lpInfo^.Params[i,0])));
    
  2. 使用您在 的第二个参数中使用的相同类型转换SetString()

    SetString(tempStr,
      PChar(@(lpInfo^.Params[i,0])),
      StrLen(PChar(@(lpInfo^.Params[i,0]))));
    
  3. 摆脱对SetString()and的调用StrLen(),因为可以将空终止字符指针直接分配给String变量:

    tempStr := PChar(@(lpInfo^.Params[i,0]));
    

    {$TYPEDADDRESS ON}
    tempStr := @(lpInfo^.Params[i,0]);
    

话虽如此,请注意Char数据类型在 D2009 中从 Ansi 更改为 Unicode,因此此代码仅在将参数发送到应用程序的 Unicode 版本时才有效,而不是 Ansi 版本。如果您需要继续支持您的应用程序的旧版本,您应该定义一个不同的窗口消息来传递 Unicode 参数,然后让您的 Unicode 应用程序支持两种消息来接收,并分析目标HWND以决定使用哪个消息来发送。

于 2016-05-12T03:07:13.617 回答