wskaźnik na procedurę a wskaźnik na metodę

0

mam problem, (chodzi o procedurę statusproc) następujące wywołanie działa bez problemu:

chan := BASS_StreamCreateURL(url, 0, BASS_STREAM_STATUS, @StatusProc, 0);

ale jeżeli chcemy by ta linia była wykonywana np w konstruktorze jakiejś klasy (wtedy i StatusProc musi być metodą tej klasy) to jak zapisać to odwołanie?

próbowałem z @self.StatusProc
próbowałem z type tproc=precedure(...)
próbowałem z addr w różnych formach
nic mi nie działa

pomocy :)

0

Popatrz na ten przykład, może będziesz mógł zrobić w ten sposób:

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);

    procedure Przemnoz(a, b: Integer); //metoda, do której chcesz podać wskaźnik
    
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

type
  TMetoda = procedure (a, b: Integer) of object; //definicja metody "Przemnoz"

procedure TForm1.Przemnoz(a, b: Integer); 
Begin
  Showmessage('Wynik: '+IntToStr(a)+'*'+IntToStr(b)+'='+IntToStr(a*b));
End;

procedure Funkcja( P: Pointer); //coś jakby Twoja funkcja BASS_StreamCreateURL(..)
Var
 Metoda: TMetoda; //zadeklarowanie definicji metody "Przemnoz"
Begin
  @Metoda:=P; //przekazanie wskaźnika na definicję metody "Przemnoz"
  Metoda(2, 5); //wykonanie metody "Przemnoz"
End;

procedure TForm1.Button1Click(Sender: TObject);
 Var
  Metoda: TMetoda; //zadeklarowanie definicji metody "Przemnoz"
begin
 Metoda:=Przemnoz; //przekazanie wskaźnika metody "Przemnoz"
 Funkcja(@Metoda); //wywołanie coś jakby Twojej funkcji BASS_StreamCreateURL(..)
end;
 

Pzdr.
Marogo

0

A czym jest StatusProc ? Czym ma być ?
czy to jest zwykła procedura czy też metoda klasy ?
To nie jest to samo :)

0

@Adamek Adam - no zostało to powiedziałne - w przykładowym wywołaniu jest to zwykła procedura ale chodzi właśnie o to żeby zrobić z niej metodę i jak ją w tedy wywołać ...
@marogo - dzięki za odpowiedź ale to nie działa - owszem można w ten sposób odwołać z się np z zewnątrz do metody danego obiektu ale mnie chodzi o wyłapanie tego adresu gdy obiektu jeszcze nie ma (np w deklaracji jakiejś jego metody) a tak działać nie chce ...

znalazłem jedno rozwiązanie - wygląda dość kuriozalnie i trochę nie chce mi się wierzyć żeby było jedyne - niemniej działa i myślę że warto się temu przyjrzeć: http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_21227859.html

0

o nie widać teraz rozwiązania ;(
skopiuję więc najważniejsze posty:

I'm writing a plugin architecture, each plugin object has an interface to each dll, the interface is defined as a class function in the plugin object, so I have to pass the entrance pointer of the class function to a dll to callback.
Thanks for the reply, I've solved the problem which a little trick of embeded asm, I'll close the question. This is my solution, hope useful for others.

========================================
procedure FreeClassProcInstance(ProcInstance: Pointer);
begin
// free memory
FreeMem(ProcInstance, 15);
end;

function MakeClassProcInstance(M: TMethod): Pointer;
begin
// allocate memory
GetMem(Result, 15);
asm
// MOV ECX,
MOV BYTE PTR [EAX], $B9
MOV ECX, M.Data
MOV DWORD PTR [EAX+$1], ECX
// POP EDX
MOV BYTE PTR [EAX+$5], $5A
// PUSH ECX
MOV BYTE PTR [EAX+$6], $51
// PUSH EDX
MOV BYTE PTR [EAX+$7], $52
// MOV ECX,
MOV BYTE PTR [EAX+$8], $B9
MOV ECX, M.Code
MOV DWORD PTR [EAX+$9], ECX
// JMP ECX
MOV BYTE PTR [EAX+$D], $FF
MOV BYTE PTR [EAX+$E], $E1
end;
end;

=================================

Simply call MakeClassProcInstance(TMethod(AClassFunctionPointer)) to retrive the pointer of the class function, and remember to call FreeClassProcInstance to reclaim memory when the pointer is no longer to use.


Slick812, here I give you a example of calling the two function:

=================
TPlatformInterface = function (const Msg, ParamA, ParamB:integer):integer of object;stdcall;

TPlugin = class
private
FPlatformInterface : TPlatformInterface;
FPlatformInterfaceInstance : Pointer;
public
constructor Create;
destructor Destroy; override;
function PlatformInterface(const Msg, ParamA, ParamB:integer):integer; stdcall;
end;

constructor TPlugin.Create;
begin
FPlatformInterface := PlatformInterface;
FPlatformInterfaceInstance := MakeClassProcInstance(TMethod(FPlatformInterface));
end;

destructor TPlugin.Destroy;
begin
FreeClassProcInstance(FPlatformInterfaceInstance);
end;

==============

now the FPlatformInterfaceInstance is a pure function pointer, you may use it as the same as other function pointers.

If you need more pointers to point to your other class methods, you have to declare more pointer variables for each class method, each instance pointer must be pointed to only one class method instance, and clear up them after you don't need them (or it will be causing memory leaks).

0

Czy nie jest tak że metoda klasy ma zawsze dodatkowy parametr self wiec lista parametrów nie powinna sie zgadzać i nie powinno działać ?
Chyba że trochę niedospany jestem i może lepiej się położę ;)

Chwałą Ci za wklejenie niewidocznej czesci kodu ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1