Ich nehme an TDECClassList war früher mal eine Liste (wahrscheinlich sogar TList wegen dem TClass-Cast). Im aktuellen Code ist die "Liste" nun ein TDictionary<Int64, TDECClass>. Der Code in ModuleUnload() geht aber weiterhin davon aus, dass es sich um eine TList handelt, deren Items TClass sind. Aber wegen dem Dictionary wird die for-Variable "i" nun nicht mehr als Index in die Liste verwendet sondern als Key ins Dictionary. Und das löst die Fehlermeldung aus, da es wahrscheinlich keinen Eintrag mit Key=0, Key=1 usw. gibt.
Dass es unter Delphi funktioniert und unter C++Builder nicht, liegt daran, dass C++Builder ModuleUnload() auch für das eigene Modul aufruft und Delphi eben nicht. Somit fällt der Fehler unter einem "
DLL/
BPL-freiem" Delphi nicht auf.
Als erstes würde ich die erste If-Anweisung um "if (Instance <> HInstance) and ..." erweitern. Der Aufruf mit der eigenen HInstance der
Unit ist nutzlos, da im finalization sowie die Liste freigegeben wird. Wenn also die
Unit aus dem eigenen Modul (
DLL,
BPL) entladen wird, muss nicht noch unnötige Extra-Arbeit geleistet werden.
Das behebt den "Index vs Key" Fehler aber noch nicht. Hierfür muss das Dictionary als Dictionary behandelt werden:
Delphi-Quellcode:
procedure ModuleUnload(Instance: NativeInt);
var // automaticaly deregistration/releasing
i: Integer;
Items: TArray<TPair<Int64, TDECCLass>>;
begin
// C++Builder calls this function for our own module, but we destroy the ClassList in that case in the finalization section anyway.
if (Instance <> HInstance) and
(TDECHash.ClassList <> nil) and (TDECHash.ClassList.Count > 0) then
begin
Items := TDECHash.ClassList.ToArray;
for i := Length(Items) - 1 downto 0 do
begin
if FindClassHInstance(Items[i].Value) = HINST(HInstance) then
TDECHash.ClassList.Remove(Items[i].Key);
end;
end;
end;
Derselbe Fehler ist übrigens auch in
- DECCipherBase.pas
- DECFormatBase.pas
- DECHashBase.pas (hier beschriebener Fehler)