I'm passing an anonymous method to an external function. The anonymous method is an integrand and the external function will calculate a definite integral. Because the integration function is external it does not understand anonymous methods. So I'm having to pass the anonymous method as an untyped pointer. To make this clearer, it runs like this:
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);
Here CalcIntegral
is the external function that will call ExternalIntegrand
. That in turn takes the untyped pointer that is passed on, retrieves the anonymous method, and gets it to do that work.
The problem is that I can't write CastToPointer
cleanly. If I do:
Pointer(Integrand)
the compiler objects with:
[dcc32 Error]: E2035 Not enough actual parameters
Clearly the compiler is trying to call the anonymous method.
I am able to do this:
function CastToPointer(const F: TFunc<Double,Double>): Pointer; inline;
begin
Move(F, Result, SizeOf(Result));
end;
or this:
function CastToPointer(const F: TFunc<Double,Double>): Pointer; inline;
var
P: Pointer absolute F;
begin
Result := P;
end;
But it seems somewhat galling that I cannot use a simple cast as I might when casting a dynamic array to a pointer to the array.
I realise that I could pass the address of the variable holding the anonymous method. Like this:
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);
However, it seems a little odd to have to introduce another level of indirection.
Does anybody know a way to cast an anonymous method variable directly to a pointer? I do realise that such skullduggery is questionable but at least out of curiosity I'd like to know if it can be done.