2017-11-23 7 views
5

に古いContnrs.TObjectListを並べ替え:我々は<code>Contnrs.TObjectList</code>を使用して、いくつかの古いクラスを持っている、といくつかのケースでは、カスタム比較関数はこのようなものを使用して、これらのリストをソートするために使用されているWin64の

procedure TMyClass.SortItems; 

    function CompareFunction(Item1, Item2: Pointer): Integer; 
    begin 
    Result := TSomeItem(Item1).Value - TSomeItem(Item2).Value; 
    end; 

begin 
    Sort(@CompareFunction); 
end; 

このコードは、なしで働いていますWin32のためにコンパイルされたときに問題が発生しますが、Win64のためにコンパイルすると、ソートがもう機能しなくなりました。

代わりにGenerics.Collections.TObjectList<T>を使用して、CompareFunctionを変更して、その一部を修正して一部を修正しました。だから私の推測は、CompareFunctionが呼び出される方法と関係していることです。それには@オペレータが付いています。これは私が理解するように、関数のアドレスを参照しています。

なぜ上記のコードはWin64では動作しないのですか?それを修正する正しい方法は何でしょうか?

答えて

7

TObjectList.Sort()は、そのコールバックのためのスタンドアロン機能が必要です。

内部関数は、親関数のスタックフレームを共有しているため(親のローカル変数とパラメータにアクセスできます)。したがって、内部関数をコールバックとして使用することはできません。あなたは32ビットで機能がどのように働くのかを知るために、32ビットでそれを取り除いた。しかしこれはもう64ビットでは動作しません。

あなたは例えば、独自にCompareFunction()を外に移動する必要があります。

function CompareFunction(Item1, Item2: Pointer): Integer; 
begin 
    Result := TSomeItem(Item1).Value - TSomeItem(Item2).Value; 
end; 

procedure TMyClass.SortItems; 
begin 
    Sort(@CompareFunction); 
end; 

これは、32ビットおよび64ビットの両方で動作します。

+0

ああ、簡単でした。ありがとう。私はそれを試してみました。スタンドアロン関数を使用するときに '@ '演算子を省略することができます。単純に' Sort(CompareFunction) 'を使用していることに気付きました。 – alondono

+0

@alondono、それに気付きました!私はあなたが何をするかを**と**強制的に知っている場合を除いて、関数ポインタのために決して '@'を使用しないという習慣に入ることを勧めます。 :-) –

関連する問題

 関連する問題