我正在将一个匿名方法传递给外部函数。这个匿名方法是被积函数,而外部函数将计算一个定积分。由于积分函数是外部的,它不理解匿名方法。因此,我必须将匿名方法作为未经类型化的指针传递。为了更清楚地说明,它的运行方式如下:
function ExternalIntegrand(data: Pointer; x: Double): Double; cdecl;
begin
Result := GetAnonMethod(data)(x);
end;
....
var
Integrand: TFunc<Double,Double>;
Integral: Double;
....
Integral := CalcIntegral(ExternalIntegrand, CastToPointer(Integrand), xlow, xhigh);
这里的CalcIntegral
是一个外部函数,它会调用ExternalIntegrand
。而ExternalIntegrand
则会接收传递过来的未命名指针,并获取匿名方法并让其工作。
问题在于我无法清晰地编写CastToPointer
。如果我这样做:
Pointer(Integrand)
编译器报错:
[dcc32 Error]: E2035 Not enough actual parameters
很明显,编译器试图调用匿名方法。
我能够做到这一点:
function CastToPointer(const F: TFunc<Double,Double>): Pointer; inline;
begin
Move(F, Result, SizeOf(Result));
end;
或者这个:
function CastToPointer(const F: TFunc<Double,Double>): Pointer; inline;
var
P: Pointer absolute F;
begin
Result := P;
end;
但是有点令人沮丧的是,在将动态数组转换为指向该数组的指针时,我无法像使用简单的强制转换那样处理它。
我意识到我可以传递保存匿名方法的变量的地址。就像这样:
function ExternalIntegrand(data: Pointer; x: Double): Double; cdecl;
var
F: ^TFunc<Double,Double>;
begin
F := data;
Result := F^(x);
end;
....
Integral := CalcIntegral(ExternalIntegrand, @Integrand, xlow, xhigh);
然而,引入另一层间接性似乎有点奇怪。
有人知道将匿名方法变量直接转换为指针的方法吗?我知道这样的做法是可疑的,但出于好奇至少想知道是否可以这样做。
ExternalIntegrand
,那么GetAnonMethod
会是什么样子呢?你肯定需要知道类型...普通的方法指针无法强制转换为TFunc<double,double>
- 难道它不需要强制转换为一些TFoo = function(x:double):double;
吗? - J...CalcIntegral
的函数将匿名方法作为参数接收,因此我已经在那一点上确定了类型。所以,我没有好好思考这个问题。我们当然可以添加一个未指定类型的指针版本的CastToPointer
,但它并不会更简洁。 - David Heffernan