背景:将我的代码移植到Delphi 10.1 Berlin并通过第三方库。有些不再可用,所以我会尝试修复代码...
以下代码(将params从一个程序实例传递到另一个实例)引发了对StrLen的E2251 Ambiguious重载调用。我理解为什么,我只是不知道解决问题的最佳方法。
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;
由于
答案 0 :(得分:1)
默认情况下,@
地址运算符会生成无类型指针。 StrLen()
有两个重载版本,一个带PAnsiChar
,另一个带PWideChar
。可以将无类型指针传递给两个重载,从而产生歧义。 Delphi 2007中不存在PWideChar
重载,这就是以前编译代码的原因。
要修复代码,您必须:
使用{$TYPEDADDRESS ON}
或{$T+}
编译器指令启用Type-checked pointers,因此使用Char
运算符获取@
变量的地址将会产生一个类型化的PChar
指针,而不是一个无类型的指针。
{$TYPEDADDRESS ON}
SetString(tempStr,
@(lpInfo^.Params[i,0]),
StrLen(@(lpInfo^.Params[i,0])));
使用您在SetString()
的第二个参数中使用的相同类型转换:
SetString(tempStr,
PChar(@(lpInfo^.Params[i,0])),
StrLen(PChar(@(lpInfo^.Params[i,0]))));
删除对SetString()
和StrLen()
的调用,因为可以将以空值终止的字符指针直接分配给String
变量:
tempStr := PChar(@(lpInfo^.Params[i,0]));
{$TYPEDADDRESS ON}
tempStr := @(lpInfo^.Params[i,0]);
说到这一点,请注意在D2009中Char
数据类型从Ansi更改为Unicode,因此此代码仅在将参数发送到应用程序的Unicode版本时才有效,而不是Ansi版本。如果您需要继续支持应用程序的旧版本,则应定义一个不同的窗口消息以传递Unicode参数,然后让您的Unicode应用程序支持两个用于接收的消息,并分析目标HWND
以决定将哪个消息发送到用于发送。