Is there a way to send an anonymous method to a pointer?

I pass an anonymous method to an external function. An anonymous method is an integrand, and an external function will calculate a certain integral. Since the integration function is external, it does not understand anonymous methods. Therefore, I need to pass the anonymous method as an untyped pointer. To make this clearer, it works as follows:

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 CalcIntegralis the external function that calls ExternalIntegrand. This, in turn, takes an untyped pointer, which is passed, retrieves an anonymous method, and gets it to do the job.

The problem is that I cannot write CastToPointercleanly. If I do this:

Pointer(Integrand)

compiler objects:

[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);

, , .

- ? , skullduggery , , , , , .

+4
2

Pointer((@Integrand)^), :

Integral := CalcIntegral(ExternalIntegrand, Pointer((@Integrand)^), xlow, xhigh);

, :)

CastToPointer, :

program Project8;

{$APPTYPE CONSOLE}

{$R *.res}

{$T+}

uses
  System.SysUtils;

  function CastToPointer(const F: TFunc<Double,Double>): Pointer; inline;
begin
  Move(F, Result, SizeOf(Result));
end;

var
  Integrand: TFunc<Double,Double>;
  Mypointer1: Pointer;
  Mypointer2: Pointer;
begin
  Integrand := function(x : double) : double
       begin
         result := 2 * x;
       end;
  Mypointer1 := Pointer((@Integrand)^);
  Mypointer2 := CastToPointer(Integrand);
  Assert(Mypointer1 = Mypointer2, 'Pointers don''t match!');
end.
+5

, , , , Pointer.

{$APPTYPE CONSOLE}

uses
  SysUtils;

function Foo(x : double) : double;
begin
  result := 4 * x;
end;

procedure Test2(const data);
begin
  WriteLn(TFunc<Double,Double>(data)(2));
end;

var
  F: TFunc<Double,Double>;
begin
  F := function(x : double) : double
       begin
         result := 2 * x;
       end;
  Test2(F);  // Anonymous method
  F := foo;
  Test2(F);  // Regular method
  ReadLn;
end.

, , TFunc .

4.00000000000000E + 0000

8.00000000000000E + 0000

, , , , .

{$APPTYPE CONSOLE}

uses
  SysUtils;

type TFoo = function(x : double) : double;

function Foo(x : double) : double;
begin
  result := 4*x;
end;

function Test2(const data) : double;
begin
  result := TFunc<Double,Double>(data)(2);
end;

function Test(data : TFoo) : double; overload;
var
  F : TFunc<double,double>;
begin
  F := data;
  result := Test2(F);
end;

function Test(data : TFunc<Double,Double>) : double; overload;
begin
  result := Test2(data);
end;

var
  F: TFunc<Double,Double>;
begin
  F := function(x:double):double
       begin
         result := 2*x;
       end;
  WriteLn(Test(F));  // Anonymous method
  WriteLn(Test(foo));  // Regular method
  ReadLn;
end.
+2

All Articles