Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi func BeginThread: fehlerhafte Parameterübergabe (https://www.delphipraxis.net/42957-func-beginthread-fehlerhafte-parameteruebergabe.html)

Nogge 26. Mär 2005 15:29


func BeginThread: fehlerhafte Parameterübergabe
 
Hallo Community,
ich habe hier ein ziemlich mysteriöses Verhalten entdeckt:
Delphi-Quellcode:
function OpenURL(url: PChar): Integer;
var icy: PChar;
begin
  Result := 0;
    //ShowMessage(url);
  Record_Channel := BASS_StreamCreateURL(url, 0, BASS_STREAM_META or
  BASS_STREAM_STATUS,@StatusProc, 0);
  {...}
end;

procedure TForm_RTRecording.Button2Click(Sender: TObject);
var ThreadId: Cardinal;
begin
  if (cthread <> 0)
  then MessageBeep(0)
  else
  cthread := BeginThread(nil, 0, @OpenURL, PChar(Edit1.Text), 0, ThreadId);
    //ShowMessage('kp wieso, aber ShowMessage muss aufgerufen werden ;_;');
end;
BeginThread wird nur dann korrekt ausgeführt, wenn ich ShowMessage('kp...') anzeigen lasse. Sonst, wenn ich ShowMessage(url) aktiviere, kommt der oben angegebene Fehler. Wieso muss ich also ShowMessage('kp...') ausführen, damit alles funktioniert?

Luckie 26. Mär 2005 15:31

Re: func BeginThread: "Canvas does not allow drawing&am
 
Nimm im Thread eine Messagebox, dann sollte es klappen. Das hängt irgendwie mit der VCL zusammen. Der ShowMessage-Dialog ist ein Eigenbau von Borland und der Canvas ist nicht threadsafe.

Nogge 26. Mär 2005 16:28

Re: func BeginThread: "Canvas does not allow drawing&am
 
Vielen Dank für den Hinweis ! Jetzt weiß ich endlich, was bei der Übergabe des Parameters nicht stimmt. Wenn ich ShowMessage('kp...') nicht anzeigen lasse, wird anstatt Edit1.Text ein Label.Caption von der selben Form übergeben :roll: :?:
Das finde ich ziemlich seltsam O_O

Luckie 26. Mär 2005 16:35

Re: func BeginThread: "Canvas does not allow drawing&am
 
So:
Delphi-Quellcode:
PChar(Edit1.Text)
übergibt man auch keine parameter an Threads. Guck dir dazu mal mein Threadingtutorial an: http://tutorials.luckie-online.de

Nogge 26. Mär 2005 17:08

Re: func BeginThread: "Canvas does not allow drawing&am
 
Ich habe diese Variante aus einem Beispiel für die Verwendung der BASS-Engine:
Delphi-Quellcode:
const
  urls: array[0..9] of String = (
    'http://64.236.34.196/stream/2001','http://205.188.234.129:8024',
    'http://64.236.34.97/stream/1006','http://206.98.167.99:8406',
    'http://160.79.1.141:8000/','http://206.98.167.99:8006',
    'http://205.188.234.4:8016','http://205.188.234.4:8014',
    'http://server2.somafm.com:8000','http://server1.somafm.com:8082'
  );

function OpenURL(url: PChar): Integer;
var
  icy: PChar;
begin
  Result := 0;
  BASS_StreamFree(Form1.chan); // close old stream
  Form1.Label4.Caption := 'connecting...';
  Form1.Label3.Caption := '';
  Form1.Label5.Caption := '';
  Form1.chan := BASS_StreamCreateURL(url, 0, BASS_STREAM_META or BASS_STREAM_STATUS,
                                                            @StatusProc, 0);
  if (Form1.chan = 0) then
  begin
    Form1.Label4.Caption := 'not playing';
    Error('Can''t play the stream');
  end
  else
  begin
    // get the broadcast name and bitrate
    icy := BASS_StreamGetTags(Form1.chan, BASS_TAG_ICY);
    if (icy <> nil) then
      while (icy^ <> #0) do
      begin
        if (Copy(icy, 1, 9) = 'icy-name:') then
          Form1.Label4.Caption := Copy(icy, 11, Length(icy) - 10)
        else if (Copy(icy, 1, 7) = 'icy-br:') then
          Form1.Label5.Caption := 'bitrate: ' + Copy(icy, 9, Length(icy) - 8);
        icy := icy + Length(icy) + 1;
      end;
    // get the stream title and set sync for subsequent titles
    DoMeta(BASS_StreamGetTags(Form1.chan,BASS_TAG_META));
    BASS_ChannelSetSync(Form1.chan,BASS_SYNC_META,0,@MetaSync,0);
    // play it!
    BASS_ChannelPlay(Form1.chan,FALSE);
  end;
  Form1.cthread := 0;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  ThreadId: Cardinal;
begin
  if (cthread <> 0) then
    MessageBeep(0)
  else
    cthread := BeginThread(nil, 0, @OpenURL, PChar(urls[TButton(Sender).Tag]), 0, ThreadId);
end;
Was ist denn bei diesem Code anders als bei meinem (mit diesem funktioniert es nämlich einwandfrei!)?

Nogge 27. Mär 2005 00:23

Re: func BeginThread: fehlerhafte Parameterübergabe
 
Ok, ich habe jetzt meinen fehler entdeckt: man darf bei dem packed record kein PChar deklarieren, sondern muss z.B. bei einem String die max Länge angeben.
Delphi-Quellcode:
type
  TParameter = packed record
    Text: String[255];
  end;
  PParameter = ^TParameter;
Jetzt funktioniert es wie gewünscht.

Nogge 11. Apr 2005 17:16

Re: func BeginThread: fehlerhafte Parameterübergabe
 
Ich habe zu dem Quellcode aus der BASS-Engine trotzdem noch mal eine Frage:
Warum kann ich hierbei dem Thread einen Parameter vom Typ PChar übergeben? Liegt es daran, dass die url-array-Strings fest definiert wurden und keinen durch den Benutzer beliebigen String enthalten kann?


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:27 Uhr.

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