Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi,在TPointerlist()处编辑tenumstring中的自动完成访问冲突_Delphi_Autocomplete_Delphi 10.1 Berlin - Fatal编程技术网

Delphi,在TPointerlist()处编辑tenumstring中的自动完成访问冲突

Delphi,在TPointerlist()处编辑tenumstring中的自动完成访问冲突,delphi,autocomplete,delphi-10.1-berlin,Delphi,Autocomplete,Delphi 10.1 Berlin,在by@KenWhite中,当调用TPointerList()[]时(通过windows自动完成界面),下一个函数存在访问冲突 D10.1u2,Win10.64 function TEnumString.Next(celt: Integer; out elt; pceltFetched: PLongint): HResult; var I: Integer; wStr: WideString; begin I := 0; while (I < celt) and (FCurrI

在by@KenWhite中,当调用
TPointerList()[]
时(通过windows自动完成界面),下一个函数存在访问冲突

D10.1u2,Win10.64

function TEnumString.Next(celt: Integer; out elt;
   pceltFetched: PLongint): HResult;
var
 I: Integer;
wStr: WideString;
begin
 I := 0;
 while (I < celt) and (FCurrIndex < FStrings.Count) do
   begin
     wStr := FStrings[FCurrIndex];
     TPointerList(elt)[1] := PWideChar('abcd');  //access violation
     TPointerList(elt)[1] := CoTaskMemAlloc(8);  //access violation
     TPointerList(elt)[I] := CoTaskMemAlloc(2 * (Length(wStr) + 1)); //access violation
     StringToWideChar(wStr, TPointerList(elt)[I], 2 * (Length(wStr) + 1));
     Inc(I);
     Inc(FCurrIndex);
  end;
 if pceltFetched <> nil then
  pceltFetched^ := I;
 if I = celt then
 Result := S_OK
else
  Result := S_FALSE;
end;
函数TEnumString.Next(celt:Integer;out-elt;
pceltFetched:PLongint):HResult;
变量
I:整数;
wStr:宽管柱;
开始
I:=0;
而(I
(英语教学)
需要是
(@elt)
,而
[1]
需要是
[I]

TPointerList(@elt)[I]
那么代码就不再是AV了

此外,输出字符串必须分配给
SysAllocString…()
CoTaskMemAlloc()
,因为调用者将使用COM内存管理器释放它们。您可以使用RTL的
ComObj.StringToLPOLESTR()
函数为您处理该问题,这将生成Delphi
字符串的COM分配宽字符串副本:

TPointerList(@elt)[I] := StringToLPOLESTR(FStrings[FCurrIndex]);
或者,您可以简单地获得
WideString
的数据指针的所有权,而不是在
WideString
已经创建了一个副本之后在内存中创建另一个副本:

wStr := FStrings[FCurrIndex];
TPointerList(@elt)[I] := Pointer(wStr);
Pointer(wStr) := nil;
在较新的版本(IIRC XE2和更高版本)中,您可以按照Remy所说的去做,但在我看来,您不应该这样做

在XE2之前的版本(或任何版本)中,
TPointerList
的定义是:

type
  ...
  TPointerList = array[0..MaxListSize] of Pointer;
在较新版本中,它是:

type
  TPointerList = array of Pointer;
换句话说,它现在已经不是静态数组类型(值类型),而是动态数组类型(引用类型)。将非类型化参数的地址强制转换为这样的数组可能会变得很棘手

定义上的差异解释了为什么在较新版本中,代码不能正常工作:存在一个额外的间接级别

现在,如果将以下声明添加到uautomplete.pas文件中:

然后文件的其余部分可以保持原来的状态。然后:

TPointerList(elt)[I] := ...

它可以工作,并且不需要您在实际不需要的情况下对Delphi动态数组使用稍微复杂的、间接的强制转换。请注意,这也适用于旧版本。

您的问题是什么。剩下的代码在哪里@DavidHeffernan那么,你的问题是什么?答案在哪里?我在这里也看不到问题。我只是看到了一个问题,一个函数,和另一个问题的链接。我也看不出大卫的评论有什么恶意。@Henry我读了你链接的全部博文,但我仍然不知道如何处理网站上发布的答案的错误报告。谢谢Remy,
TPointerList(@elt)[I]:=StringToLPOLESTR(FStrings[fcurridex])修复了它。奇怪的是,原来的代码似乎已被多人成功使用,包括我们尊敬的DH注意到
TPointerList
的定义已更改,Delphi XE2中的IIRC。XE2之前是指针的
TPointerList=array[0..MaxListSize-1]。在XE2中,它变成
TPointerList=指针数组。这可以解释为什么原来的示例代码在新版本中不再工作了:有一个额外的间接层。我认为,在这里转换成动态数组也有点问题。@RudyVelthuis-true,这就是为什么我根本不喜欢使用
TPointerList
。我可能只是将
elt
转换为
PPointer
,并在每个循环迭代中递增+取消引用它。事实上,这回答了“链接是一个完整的工作示例”的问题。这是唯一一个类似于OP发布的问题,尽管它是在评论中被问到的,尽管并不确切知道它的意思。
TPointerList(elt)[I] := ...