We have some old classes using Contnrs.TObjectList
, and in some cases custom compare-functions are used to sort these lists, using something like this:
procedure TMyClass.SortItems;
function CompareFunction(Item1, Item2: Pointer): Integer;
begin
Result := TSomeItem(Item1).Value - TSomeItem(Item2).Value;
end;
begin
Sort(@CompareFunction);
end;
This code has worked without issues when compiled for Win32, but when we compile it for Win64, we have found that the sorting doesn't work anymore.
I have fixed some of them by using Generics.Collections.TObjectList<T>
instead, and modifying the CompareFunction
and how it is called. So my guess is that it has to do with the way the CompareFunction
is called, by prefixing it with the @
operator, which as I understand, refers to the address of the function.
Why does the code above doesn't work on Win64, and what would be the proper way to fix it?
TObjectList.Sort()
expects a standalone function for its callback.
An inner function shares the stack frame of its parent function (so it can access the parent's local variables and parameters). So you can't use an inner function as the callback. You got away with it in 32bit, due to a fluke in how functions work in 32bit. But this won't work anymore in 64bit.
You need to move CompareFunction()
out on its own, eg:
function CompareFunction(Item1, Item2: Pointer): Integer;
begin
Result := TSomeItem(Item1).Value - TSomeItem(Item2).Value;
end;
procedure TMyClass.SortItems;
begin
Sort(@CompareFunction);
end;
This will work in both 32bit and 64bit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With