私は JCL の式評価器 TEvaluator (barry kelly によって寄贈された素晴らしい作品) を使用しています。(ありがとうバリー!)
バックグラウンド
AddFunc メソッドを使用しました。
function MyFunc:double;
begin
// calculations here
Result:=1;
end;
AddFunc メソッドを使用して、関数を使用可能にすることができます。
AddFunc('MyFunc', MyFunc);
ここに問題があります...
スタンドアロン ルーチンではなく、オブジェクトのメソッドを呼び出す必要があります。
その理由は、値を提供するオブジェクトのリストがあるからです。
車両オブジェクトのリストがあるとします。各オブジェクトには重み関数があります。各オブジェクトの重みを数式で使用できるようにしたいと考えています。
ばかげた例ですが、説明は簡単です。
type
TVehicle=class
private
public
function Weight:double;
end;
function StrangeCalculation:double;
var
vehicle:TVehicle;
begin
for iVehicle = 0 to Count - 1 do
begin
vehicle:=GetVehicle(iVehicle);
// E2250 There is no overloaded version of 'AddFunc' that can be called with these arguments
eval.AddFunc(vehicle.Name, vehicle.Weight);
end;
Result:=eval.Evaluate('JeepTJWeight + FordF150Weight * 2');
end;
私のオプション:
AddVar( ) または AddConst( ) -- しかし、値が使用できない場合に例外を発生させる必要があるため、これはあまり優れていません。
AddFunc( ) とスタンドアロン関数。変数の名前 (および数) は実行時まで不明であるため、これを行うことはできません。
変数が見つからない場合は、オブジェクトを変更してコールバックを追加します。私は実際にこれを行いましたが、ソースのコピーを編集してコールバックしてこれを行う必要がありました。
メソッド関数を使用できる AddFunc( ) を作成します。
オプション #3 は実際には構築されていますが、追加の AddFunc の方が適切です。問題は、どのメソッド プロトタイプを提供すればよいかわからないことです。私はTMethodがその方法だと思っていましたが、私の知識はここではあまりにも限られています...これは私の失敗した試みでしたが、eval.AddFuncで「E2250これらの引数で呼び出すことができる 'AddFunc'のオーバーロードされたバージョンはありません」というメッセージが表示されます() 以前のように呼び出します。
TFloat64MethodFunc = function(c:pointer): TFloat64;
procedure TEasyEvaluator.AddFunc(const AName: string; AFunc: TFloat64MethodFunc);
begin
FOwnContext.Add(TExprFloat64MethodFuncSym.Create(AName, AFunc));
end;
TExprFloat64MethodFuncSym = class(TExprAbstractFuncSym)
private
FFunc: TFloat64MethodFunc;
public
constructor Create(const AIdent: string; AFunc: TFloat64MethodFunc);
function Evaluate: TFloat; override;
// not using function Compile: TExprNode; override;
end;
ご協力ありがとうございました!
mp