Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Objektmethode als Objective-C Callback (https://www.delphipraxis.net/207764-objektmethode-als-objective-c-callback.html)

LairdTurner 30. Apr 2021 16:11

Delphi-Version: 10.4 Sydney

Objektmethode als Objective-C Callback
 
Hallo!

In den Wrappern für iOS von Delphi habe ich bspw. folgende Deklaration
Code:
AURenderCallbackStruct = record
    inputProc: AURenderCallback;
    inputProcRefCon: Pointer;
  end;
AURenderCallback = function(param1: Pointer; param2: PAudioUnitRenderActionFlags; param3: PInteger; param4: UInt32; param5: UInt32; param6: PInteger): OSStatus; cdecl;
Wie kann ich an die Variable inputProc eine Objektfunktion anhängen?
Bisher verwende ich hierfür eine globale Funktion bzw. eine statische Klassenfunktion.
Bei letzter verliere ich aber den Zugriff auf die Objektvariablen.
Ich möchte es aber gerne über eine Objektfunktion lösen, da ich hier heraus auch noch Events triggern möchte.

Ich weiss um den Umstand, dass Delphi bei Objektfunktionen immer implizit self als ersten Parameter mitgibt.
Aus diesem Grund funktioniert der direkte Zuweis nicht.

Es wäre nett, wenn mir jemand das Erklären und mir eine Lösung aufweisen könnte.
Ich stehe momentan komplett auf dem Schlauch!


Vielen Dank!

TiGü 30. Apr 2021 16:37

AW: Objektmethode als Objective-C Callback
 
Der erste Parameter sieht laut Doku so aus, als ob du dir da einen Zeiger auf selbst definierte Daten hineingeben kannst.
https://developer.apple.com/document...rendercallback

Du musst also weiterhin wie gehabt vorgehen mit statisch oder Klassenfunktion, aber kannst auf deine lebende Instanz casten.

Delphi-Quellcode:
function DeineImplementierungVonAURenderCallback(param1: Pointer; param2: PAudioUnitRenderActionFlags; param3: PInteger; param4: UInt32; param5: UInt32; param6: PInteger): OSStatus; cdecl;
var
  BeispielNameFürDeineInstanz: TBeispielKlassenName;
begin
  BeispielNameFürDeineInstanz:= TBeispielKlassenName(param1);
  BeispielNameFürDeineInstanz.DeinMethodenAufruf();
  BeispielNameFürDeineInstance.AndererMethodenAufrufMitDenParametern(param2, param3, param4, param5);

  Result := 0; // oder was auch immer man da als OSStatus zurückgibt.
end;

TiGü 30. Apr 2021 16:47

AW: Objektmethode als Objective-C Callback
 
Der Vollständigkeit halber:
https://developer.apple.com/document...ddrendernotify

Delphi-Quellcode:
var
  BeispielNameFürDeineInstanz: TBeispielKlassenName;

begin
  BeispielNameFürDeineInstanz := TBeispielKlassenName.Create;
  AudioUnitAddRenderNotify(ZeigerAufAudioUnitVonIrgendwoher, DeineImplementierungVonAURenderCallback, BeispielNameFürDeineInstanz);
Und ich würde an deiner Stelle die Parameter der Callback gemäß der Doku benennen, macht das Leben leichter.
Also inRefCon, ioActionFlags, inTimeStamp...anstatt param1, param2, param3.

LairdTurner 30. Apr 2021 16:52

AW: Objektmethode als Objective-C Callback
 
Hallo!

Ich stehe das immer noch auf dem Schlauch.
Wäre es eventuell Möglich ein komplettes Beispiel anzugeben?

Viellicht war der Tag heute auch zu lang! :lol:

TiGü 30. Apr 2021 16:55

AW: Objektmethode als Objective-C Callback
 
Zeig mal, was du bisher hast.

TiGü 30. Apr 2021 16:59

AW: Objektmethode als Objective-C Callback
 
Schaue dir auch dieses Swift-Beispiel an:
https://stackoverflow.com/a/41388782

LairdTurner 30. Apr 2021 17:04

AW: Objektmethode als Objective-C Callback
 
Hi!

Ich kann da im Moment nix zeigen, da ich es im Moment so gelöst habe
Code:
  TMyCallbackClass = class
  public
    class function OutputCallback(inRefCon: Pointer; ioActionFlags: PAudioUnitRenderActionFlags; inTimeStamp: PInteger;
      inBusNumber, inNumberFrames: UInt32; ioData: PInteger): OSStatus; static;
    property OnVUMeterEvent: TVUMeterEvent read FVUMeterEvent write FVUMeterEvent;
  end;
Dann hänge ich die Methode an
Code:
outputcallbackStruct.inputProc := @TMyCallbackClass.OutputCallback;
Das ist ja ein grundsätzliches Problem....
Wenn ich eine Dll selbst schreibe bzw. dll's verwende kann ich mir einen entsprechenden Wrapper bauen, aber irgendwie fehlt mir hier das verständnis für
die Funktion Pointer etc. in Verbindung mit den erzeugten Objective-C-Wrappern?

TiGü 30. Apr 2021 17:18

AW: Objektmethode als Objective-C Callback
 
Delphi-Quellcode:
var
  KlugerVariablenName: TMyCallbackClass; //für diese Beispielzeilen lokal, ist aber wohl irgendwo eine Membervariable im übergeordneten Kontext sein!?
begin
  KlugerVariablenName := TMyCallbackClass.Create;

  outputcallbackStruct.inputProc := @TMyCallbackClass.OutputCallback;
  outputcallbackStruct.inputProcRefCon := KlugerVariablenName // oder @KlugerVariablenName -> Compiler wirds dir sagen    
end;
Delphi-Quellcode:

class function TMyCallbackClass.OutputCallback(inRefCon: Pointer; ioActionFlags: PAudioUnitRenderActionFlags; inTimeStamp: PInteger; inBusNumber, inNumberFrames: UInt32; ioData: PInteger): OSStatus;
var
  Instance: TMyCallbackClass;
begin
  if inRefCon <> nil then
  begin
    Instance := TMyCallbackClass(inRefCon);
    Instance.RufeVUMeterEventAuf(); // Beispiel! 
  end;
end;

LairdTurner 1. Mai 2021 09:30

AW: Objektmethode als Objective-C Callback
 
Hallo!

Leider funktioniert das nicht
Code:
outputcallbackStruct.inputProcRefCon := KlugerVariablenName
Egal ob man nun 'nil', oder die Referenzvariable übergibt geht er im Anschluss immer in das if

Code:
class function TMyCallbackClass.OutputCallback(inRefCon: Pointer; ioActionFlags: PAudioUnitRenderActionFlags; inTimeStamp: PInteger; inBusNumber, inNumberFrames: UInt32; ioData: PInteger): OSStatus;
var
  Instance: TMyCallbackClass;
begin
  if inRefCon <> nil then
  begin
    Instance := TMyCallbackClass(inRefCon);
    Instance.RufeVUMeterEventAuf(); // Beispiel!
  end;
end;
rein.

Da scheint der Pointer nicht richtig gesetzt zu werden, denn auch wenn ich die Referenz übergebe, dann erhalte ich eine Ausnahmeverletzung bei der Abarbeitung des Events, denn der Compiler erkennt die Membervariable 'FVUMeterEvent' als Assigned, obwohl sie nicht Assigned ist

Code:
procedure TMyCallbackClass.RufeVUMeterEventAuf;
begin
  if Assigned(FVUMeterEvent) then
  begin
    FVUMeterEvent;
  end;
end;
also an dem Event nichts angehängt wurde.

TiGü 3. Mai 2021 11:47

AW: Objektmethode als Objective-C Callback
 
Was sagt denn der Debugger?
Wie sind die Werte für (ja, ich will Pointer sehen) KlugerVariablenName, outputcallbackStruct.inputProcRefCon, inRefCon, Instance?

Oder sind es vielleicht die Daten selbst?
Ändert sich der Pointer inRefCon bei jedem Aufruf der Callback?
Diese SO-Antwort deutet es an: https://stackoverflow.com/a/61213737


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:19 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz