Accessing Helper Functions / Procedures from DPR or Other Functions / Procedures in Delphi

As far as I know - Subroutines with a private mode of access to its original command / procedure, right?

Is there a way to access them from the "outside world" - dpr or another function / procedure in a block?

Also - which path requires more computation and space for the compiled file?

eg:

function blablabla(parameter : tparameter) : abcde;
 procedure xyz(par_ : tpar_);
 begin
  // ...
 end;
begin
 // ...
end;

procedure albalbalb(param : tparam) : www;
begin
 xyz(par_ : tpar_); // is there any way to make this function public / published to access it therefore enabling to call it this way?
end;

// all text is random.

// also, is there way to call it from DPR in this manner?

// in C++ this can be done by specifing access mode and/or using "Friend" class .. but in DELPHI?
+3
source share
4 answers

Note: built-in procedures <> private / protected methods.

, . , , .

:

procedure DoThis;

function DoThat : Boolean;
begin
  // This Routine is embedded or internal routine.
end;
begin

// DoThat() can only be accessed from here no other place.

end;

, Delphi 2010 RTTI. , .

, , . .

, Hack . .

+5

/ - , , , (, , / ) , . - Delphi , "" . , . AFAIK Delphi/Pascal - , . , , IIRC. AFAIK "friend" class/functions ++ - , /. Delphi /, , "", Delphi strict private. , , :

  type
    TExample = class
    private
      procedure HelloWorld;
    public
    ...
    end;

  implementation

    function DoSomething(AExample: TExample);
    begin
      // Calling a private method here works
      AExample.HelloWordl;
    end;
+7

, , () . . .

(32 )

Delphi :

// This code does not compile:
procedure testpass(p: tprocedure);
begin
  p;
end;
procedure calltestpass;
 procedure inner;
 begin
   showmessage('hello');
 end;
begin
  testpass(inner);
end;

:

// This code compiles and runs OK
procedure testpass(p: pointer);
begin
  tProcedure(p);
end;
procedure calltestpass;
 procedure inner;
 begin
   showmessage('hello');
 end;
begin
  testpass(@inner);
end;

: "" , , "" testpass ( callTestpass - , callTestpass - ), , , :

// This code compiles OK but generates runtime exception (could even be
//  EMachineHangs :-) )
procedure testpass(p: pointer);
begin
  tProcedure(p);
end;
procedure calltestpass;
var msg: string;
 procedure inner;
 begin
   msg := 'hello';
   showmessage(msg);
 end;
begin
  testpass(@inner);
end;

, "" "" ( Delphi, ). "inner" "testpass".

// This code compiles and runs OK
{$O-}
procedure testpass(p: pointer);
var callersBP: longint;
begin
  asm // get caller base pointer value at the very beginning
    push dword ptr [ebp]
    pop callersBP
  end;
// here we can have some other OP code
  asm // pushes caller base pointer value onto stack and calls tProcedure(p)
    push CallersBP
    Call p
    Pop  CallersBP
  end;
// here we can have some other OP code
end;
{$O+}

procedure calltestpass;
var msg: string;
 procedure inner;
 begin
   msg := 'hello';
   showmessage(msg);
 end;
begin
  testpass(@inner);
end;

, . OP/.

+3

, , . xyz blablabla. xyz , . ++ , , .

xyz blablabla, xyz . , . uses, xyz , , DPR .

If it xyzrelates to variables or function parameters blablabla, you need to pass them as parameters, since xyzit will no longer have access to them.

The concept of access specifiers is not very important here, since we are not talking about classes. Blocks have interface and implementation sections that do not actually match the public and private sections of the class.

+2
source

Source: https://habr.com/ru/post/1746198/


All Articles