[geschlossen] RTL_SDR Funktion tlsdr_read_async

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
Antworten
Benutzeravatar
juelin
Beiträge: 290
Registriert: Sa 24. Jul 2021, 18:03
OS, Lazarus, FPC: Linux Ubuntu 22. Windows 10 Delphi 11.3 (L 0.9.xy FPC 2.2.z)
CPU-Target: 64Bit
Wohnort: Mannheim

[geschlossen] RTL_SDR Funktion tlsdr_read_async

Beitrag von juelin »

Hallo,
muss nochmal Fragen.
Die Funktion rtlsdr_read_async soll empfangene Daten vom SDR holen und in meinen Puffer stellen.

In C ist zu der Funktion folgendes codiert:

Code: Alles auswählen

// in rtl_sdr.h
#define rtlsdr_read_async_cb_t cb = void  rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx)
RTLSDR_API int rtlsdr_read_async(rtlsdr_dev_t *dev,
				 rtlsdr_read_async_cb_t cb,
				 void *ctx,
				 uint32_t buf_num,
				 uint32_t buf_len);

// in rtl_adsb.c
#define DEFAULT_ASYNC_BUF_NUMBER	12
#define DEFAULT_BUF_LENGTH		(16 * 16384)
static rtlsdr_dev_t *dev = NULL;

static void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx)
{
	memcpy(buffer, buf, len);
}

int main(int argc, char **argv)
{
	rtlsdr_read_async(dev, rtlsdr_callback, (void *)(NULL),
			      DEFAULT_ASYNC_BUF_NUMBER,
			      DEFAULT_BUF_LENGTH);
}
In Pascal benutze ich rtl_sdr.pas und librtlsdr64.dll (beide im Anhang)
und habe ich folgendes codiert:

Code: Alles auswählen

// in rtl_sdr.pas
type
  Trtlsdr_read_async_cb_t = procedure(buf: pbyte; len: Tuint32_t; ctx: pointer); cdecl;
function rtlsdr_read_async(dev: Prtlsdr_dev_t; cb: Trtlsdr_read_async_cb_t; ctx: pointer; buf_num: Tuint32_t; buf_len: Tuint32_t): longint; cdecl; external librtlsdr;

// Unit1.pas
type
  TForm1 = class(TForm)
  private
    procedure rtlsdr_callback(buf: pbyte; len: Tuint32_t; ctx: pointer);

  const DEFAULT_ASYNC_BUF_NUMBER: Tuint32_t = 12;
  const DEFAULT_BUF_LENGTH: Tuint32_t = 16*16384;
  var sdropennum: Prtlsdr_dev_t;
  var buffer: ^byte;
//  mit GetMem(buffer, DEFAULT_BUF_LENGTH * sizeof(byte)); habe ich Speicher allociert

procedure TForm1.rtlsdr_callback(buf: pbyte; len: Tuint32_t; ctx: pointer);
begin
  move(buffer, buf, len);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
  var
    h1: Trtlsdr_read_async_cb_t;
    h2: pointer;
    h3: Tuint32_t;
    h4: Tuint32_t;
    h5: longint;
begin
  h1:=???
  h2:=???
  h3:=DEFAULT_ASYNC_BUF_NUMBER;
  h4:=DEFAULT_BUF_LENGTH;
  h5:=rtlsdr_read_async(sdropennum, h1, h2, h3, h4);
end;  
Frage was muss in die Variablen h1 und h2 rein???

hatte mal für h1: h1:=rtlsdr_read_async(sdropennum, rtlsdr_callback(&buffer, DEFAULT_BUF_LENGTH, nil), @buffer, DEFAULT_ASYNC_BUF_NUMBER, DEFAULT_BUF_LENGTH); angedacht.
da kommt aber die Fehlermeldung:
unit1.pas(188,86) Error: Incompatible type for arg no. 2: Got "untyped", expected "<procedure variable type of procedure(PByte;LongWord;Pointer);CDecl>"

h2 könnte eventuell nil sein.

Ich hoffe auf eine Lösung.

Danke und Gruß
Jürgen
Dateianhänge
rtl_sdr.zip
(521.94 KiB) 99-mal heruntergeladen
Zuletzt geändert von juelin am Fr 13. Jun 2025, 06:47, insgesamt 1-mal geändert.

Benutzeravatar
Zvoni
Beiträge: 396
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: RTL_SDR Funktion tlsdr_read_async

Beitrag von Zvoni »

1)

Code: Alles auswählen

type
  Trtlsdr_read_async_cb_t = procedure(buf: pbyte; len: Tuint32_t; ctx: pointer); cdecl;
  // wird zu, da du den Callback als Methode deiner Form nutzen willst

  Trtlsdr_read_async_cb_t = procedure(buf: pbyte; len: Tuint32_t; ctx: pointer) of object; cdecl;
2)

Code: Alles auswählen

h1:=rtlsdr_read_async(sdropennum, rtlsdr_callback(&buffer, DEFAULT_BUF_LENGTH, nil), @buffer, DEFAULT_ASYNC_BUF_NUMBER, DEFAULT_BUF_LENGTH); 
//wird zu 
h1:=rtlsdr_read_async(sdropennum, rtlsdr_callback, buffer, DEFAULT_ASYNC_BUF_NUMBER, DEFAULT_BUF_LENGTH); //"buffer" ist schon ein Zeiger --> @Buffer wäre Zeiger auf Zeiger 
Alles ungetestet
Zuletzt geändert von Zvoni am Do 12. Jun 2025, 10:12, insgesamt 1-mal geändert.
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Benutzeravatar
theo
Beiträge: 10916
Registriert: Mo 11. Sep 2006, 19:01

Re: RTL_SDR Funktion tlsdr_read_async

Beitrag von theo »

Soweit mir bekannt ist, darf die Callback Prozedur (rtlsdr_callback) keine Methode sein, sondern muss eine normale Prozedur ausserhalb der Klasse sein. Ggf kann man in ctx einen Zeiger auf eine Referenz mitgeben (z.B. ein Objekt).
Weiter habe ich es jetzt nicht angeschaut.

Benutzeravatar
Zvoni
Beiträge: 396
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: RTL_SDR Funktion tlsdr_read_async

Beitrag von Zvoni »

theo hat geschrieben: Do 12. Jun 2025, 09:52 Soweit mir bekannt ist, darf die Callback Prozedur (rtlsdr_callback) keine Methode sein, sondern muss eine normale Prozedur ausserhalb der Klasse sein. Ggf kann man in ctx einen Zeiger auf eine Referenz mitgeben (z.B. ein Objekt).
Weiter habe ich es jetzt nicht angeschaut.
Danke, theo.
Genau da war/bin ich mir nämlich auch nicht sicher.

btw hab ich mir mal den Quellcode der librtlsdr.c angeschaut
Sieht jetzt auch nicht wirklich nach Raketenwissenschaft aus.

Was mir aber an Jürgens code mehr und mehr auffällt ist die "native" Übersetzung der Datentypen.
Eigentlich soll man doch die Typen aus der ctypes-unit für solche Sachen verwenden
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Benutzeravatar
juelin
Beiträge: 290
Registriert: Sa 24. Jul 2021, 18:03
OS, Lazarus, FPC: Linux Ubuntu 22. Windows 10 Delphi 11.3 (L 0.9.xy FPC 2.2.z)
CPU-Target: 64Bit
Wohnort: Mannheim

Re: RTL_SDR Funktion tlsdr_read_async

Beitrag von juelin »

Hallo,
habe die Anregung von Zvoni ausprobiert.
of object in der Declaration von Trtlsdr_read_async_cb_t bringt gar nix.
Und wenn ich die Variablen bei tlsdr_callback weg lasse meckert der Compiler
die Anzahl Parameter an.

theo was für ein object meinst du bei dem ctx Zeiger?

Habe inzwischen raus gefunden, dass das Problem im Aufruf der procedure liegt.

Code: Alles auswählen

  var
    h3: Trtlsdr_read_async_cb_t;
    h4: Tuint32_t;
    h5: pointer;
    h6: pbyte;
    
  h4:=DEFAULT_BUF_LENGTH;
  h5:=nil;
  h6:=&buffer;
  h3:=rtlsdr_callback(h6, h4, h5);
Die Fehlermeldung kommt beim laden von h3:=rtlsdr_callback(h6, h4, h5);
unit1.pas Error: Incompatible type for arg no. 2: Got "untyped", expected "<procedure variable type of procedure(PByte;LongWord;Pointer);CDecl>"
Also wir brauchen gar nicht erst die Funktion tlsdr_read_async.

Danke und Gruß
Jürgen

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6845
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: RTL_SDR Funktion tlsdr_read_async

Beitrag von af0815 »

Zvoni hat geschrieben: Do 12. Jun 2025, 10:10 Was mir aber an Jürgens code mehr und mehr auffällt ist die "native" Übersetzung der Datentypen.
Eigentlich soll man doch die Typen aus der ctypes-unit für solche Sachen verwenden
Wenn man es weiss bzw. damit umgehen kann.

Eigentlich gehört da ein Wrapper geschrieben, der die Umsetzung Pascal <-> C macht. Das muss aber ein Wissender machen. Nachdem das aber in die Hardware geht und die Hardware nicht unbedingt die populärste ist, ist halt gefrickel angesagt.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
theo
Beiträge: 10916
Registriert: Mo 11. Sep 2006, 19:01

Re: RTL_SDR Funktion tlsdr_read_async

Beitrag von theo »

juelin hat geschrieben: Do 12. Jun 2025, 10:43

Code: Alles auswählen

  h6:=&buffer;
  
Ich würde dir raten, die Arbeit mal kurz zur Seite zu legen und die Grundlagen zu Zeigern in Pascal noch einmal anzuschauen.
& hat mit Zeigern nichts zu tun in Pascal, das ist C.
Z.B.
https://de.wikibooks.org/wiki/Programmi ... al:_Zeiger

Benutzeravatar
Zvoni
Beiträge: 396
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: RTL_SDR Funktion tlsdr_read_async

Beitrag von Zvoni »

OK, ich hab mal in Jürgens rtlsdr.pas reingeschaut.....

Ich schmeiss mich weg vor lachen.....

Code: Alles auswählen

type
  Tuint8_t = uint8;
  Puint8_t = Tuint8_t;
  Tuint16_t = uint16;
  Puint16_t = Tuint16_t;
  Tuint32_t = uint32;
  Puint32_t = Tuint32_t;

  Trtlsdr_dev_t = record end;

  Prtlsdr_dev_t = ^Trtlsdr_dev_t;
  PPrtlsdr_dev_t = ^Prtlsdr_dev_t;
Finde den Fehler.....

Ganz zu schweigen von, dass da definitiv Sachen komplett fehlen (enum rtlsdr_tuner z.B. wird zu einzelnen Konstanten "übersetzt").

@Jürgen: Wirf die rtl-sdr.pas dorthin wo sie hingehört: In die Tonne
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Mathias
Beiträge: 6952
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: RTL_SDR Funktion tlsdr_read_async

Beitrag von Mathias »

Ganz zu schweigen von, dass da definitiv Sachen komplett fehlen (enum rtlsdr_tuner z.B. wird zu einzelnen Konstanten "übersetzt").
Wen dir dies nicht passt, kannst du praktisch alle Bindungen welche bei Lazarus dabei sind wegwerfen, inklusive GLIB2 und GTK2.
Dies ist gang und gäbe, das c-Enums in Pascal als Konstante abgebildet werden. ausser du hast Freude, wen man alles casten muss.

Ich gebe es zu, das hat sich ein Fehler eingeschlichen. Aber du darfst gerne mitmachen und eine bessere Bindung bringen.

Code: Alles auswählen

type
  Tuint8_t = uint8;
  Puint8_t = ^Tuint8_t;
  Tuint16_t = uint16;
  Puint16_t = ^Tuint16_t;
  Tuint32_t = uint32;
  Puint32_t = ^Tuint32_t;  
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
Zvoni
Beiträge: 396
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: RTL_SDR Funktion tlsdr_read_async

Beitrag von Zvoni »

Mathias hat geschrieben: Do 12. Jun 2025, 13:25 Wen dir dies nicht passt, kannst du praktisch alle Bindungen welche bei Lazarus dabei sind wegwerfen, inklusive GLIB2 und GTK2.
Dies ist gang und gäbe, das c-Enums in Pascal als Konstante abgebildet werden. ausser du hast Freude, wen man alles casten muss.
OK, akzeptiert. Hast Recht. Schlechtes Beispiel mit Enums. Ist jetzt schon 3-4 Jahre her, dass ich irgendwas in Richtung C-Bindings gemacht habe
Ich gebe es zu, das hat sich ein Fehler eingeschlichen. Aber du darfst gerne mitmachen und eine bessere Bindung bringen.

Code: Alles auswählen

type
  Tuint8_t = uint8;
  Puint8_t = ^Tuint8_t;
  Tuint16_t = uint16;
  Puint16_t = ^Tuint16_t;
  Tuint32_t = uint32;
  Puint32_t = ^Tuint32_t;  
Hätte ich kein Problem damit.
Mir gings eher darum, dass Jürgen diese automatisch generierten Bindings einfach 1:1 übernommen hat, und sich dann wundert, wieso es knallt.
UNd es hätte spätestens wieder geknallt, wenn man die Zeiger auf die Integers an eine Funktion der rtl-sdr übergeben muss.

Stimme Theo zu: Jürgen sollte sich erstmal in die Thematik Zeiger einarbeiten, und als zweites das Zusammenspiel zwischen Pascal und C
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Mathias
Beiträge: 6952
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: RTL_SDR Funktion tlsdr_read_async

Beitrag von Mathias »

OK, akzeptiert. Hast Recht. Schlechtes Beispiel mit Enums. Ist jetzt schon 3-4 Jahre her, dass ich irgendwas in Richtung C-Bindings gemacht habe
Mit den enums kann man sich streiten wie man es macht.
Macht man ein echtes Pascal enum, dann hat man eine saubere Typenprüfung, aber sobald man verschiedene enum-Elemente mit or Verknüpfen muss, hat man eine riessen Casterei. aus diesen Grund mache ich es nur noch mit const. Und das mit dem or ist in C gang und gäbe.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
Zvoni
Beiträge: 396
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: RTL_SDR Funktion tlsdr_read_async

Beitrag von Zvoni »

Mathias hat geschrieben: Do 12. Jun 2025, 13:52
OK, akzeptiert. Hast Recht. Schlechtes Beispiel mit Enums. Ist jetzt schon 3-4 Jahre her, dass ich irgendwas in Richtung C-Bindings gemacht habe
Mit den enums kann man sich streiten wie man es macht.
Macht man ein echtes Pascal enum, dann hat man eine saubere Typenprüfung, aber sobald man verschiedene enum-Elemente mit or Verknüpfen muss, hat man eine riessen Casterei. aus diesen Grund mache ich es nur noch mit const. Und das mit dem or ist in C gang und gäbe.
Da ich in der Vergangenheit C-Bindings immer von Hand gemacht habe, waren C-Enums bei mir eben Pascal-Enums.
Nennen wir es "Muscle-Memory" :lol:

Ja, die Thematik mit "Wert-Sprüngen" innerhalb der enums ist ja ne Diskussion für sich, und auch die von dir erwähnten Logischen Operationen machen es nicht einfacher, aber dann wiederum reicht eigentlich ein Blick in den C-Quellcode selbst (statt nur den Header-Dateien), und schon kann man sehen, wie was verwendet wird.

Und die von mir oben genannte Enum ist mWn nur ein Funktions-Rückgabe-Type (Was für einen Tuner haben wir hier?).
Habs zumindest nicht weiter irgendwo gesehen
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Antworten