Registriert seit: 1. Feb 2004
61 Beiträge
Delphi 6 Personal
|
Access Violation bei Sendmessage nach einiger Zeit?!
2. Jan 2008, 14:50
Hallo zusammen,
ich habe ein (für mich) ziemlich mysteriöses Problem:
Ich habe drei Programme am laufen. Das eine dient zur Verwaltung von bestimmten Daten (in diesem Fall eine Playlist mit Musikstücken). Die anderen beiden enthalten jeweils den eigentlichen Player.
Das Hauptprogramm übergibt Nachrichten an die beiden Player wie "lade Lied ...", "setze Lautstärke..." etc.
Der Sinn des Programms liegt darin, dass die Liste mit Musikstücken abgearbeitet werden soll. Jeweils vor dem Ende des einen Liedes wird das nächste Lied auf dem anderen Player gestartet und die Lautstärke des einen gesenkt während die andere erhöht wird - ein faden also.
Im Hauptprogramm gibt es zwei Prozeduren für das versenden der Daten und zwei zum Empfangen (eine für jeden Player). Im jeweiligen Player gibt es je eine Prozedur zum versenden und eine zum empfangen.
Soweit alles gut, alles geht perfekt.
Wenn das Hauptprogramm aber einige Zeit gelaufen ist, kommt eine Access Violation at (irgendeine Adresse) write0000000.
Genaugenommen kommen nacheinander sehr viele solche Meldungen, die teilweise andere Adressen als die erste Meldung haben, dann wird auch über ein READ statt WRITE gemeckert.
Die Programme kann ich dann nur noch "Hart" beenden.
Das Hauptprogramm übergibt (abgesehen von den Fade-Vorgang) eher selten Daten an die anderen Progs.
Das Fading erfolgt in 100 Schritten - und somit 100 Messages (Prozent halt) und läuft in 5 Sekunden ab. Die Player übergeben an das Hauptprog (sofern sie etwas abspielen) die aktuelle Position alle 500 Millisekunden.
Wie gesagt im Großen und Ganzen gehts aber halt nach einiger Laufzeit nicht mehr (etwa 30-45 Min)
Für das Senden / Empfangen vom Hauptprogramm zum Player 1 wird WM_User + 1
Für das Senden / Empfangen vom Hauptprogramm zum Player 1 wird WM_User + 2
Für das Senden / Empfangen vom Player 1 zum Hauptprogramm wird WM_User + 3
Für das Senden / Empfangen vom Player 2 zum Hauptprogramm wird WM_User + 4
benutzt. Ansonsten sind die einzelnen Prozeduren sehr ähnlich aufgebaut.
Die Inhalte der Prozeduren basieren im wesentlichen auf Hinweisen aus dem Forum.
Leider habe ich keine Ahnung warum der Fehler auftritt - bzw. warum er nicht sofort auftritt.
Kann es sein, dass die Speicherbereiche irgendwie zu eng aneinanderliegen und so ein ungewolltes Kaputtmachen der Daten erfolgt?
Oder muß etwas bei dem CreateFileMapping beachtet werden (da steht ja immer der gleiche Wert drin)?
Was genau gibt der WM_User eigentlich an (Bytes)? oder ist das nur so ne Art ID?
Muß ich irgendwie die Länge der Nachrichten bei der Deklaration beachten?
Kann jemand helfen?
Wahrscheinlich habe ich Tomaten auf den Augen oder so.
Hauptprogramm:
Delphi-Quellcode:
procedure TMix_Player_f.Send_Message_Player_1(Sender: TObject);
var LHandle: Cardinal;
begin
fFileHandle_s1 := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, length(sendtext_1) + 1, 'Player1');
if fFileHandle_s1 <> 0 then
begin
FSpeicher := MapViewOfFile(fFileHandle_s1, FILE_MAP_WRITE, 0, 0, 0);
StrCopy(FSpeicher, PChar(sendtext_1));
LHandle := FindWindow('TMixPlayer_1_f', nil);
if LHandle <> 0 then
begin
SendMessage(LHandle, WM_USER + 1, 0, 0);
end;
CloseHandle(fFileHandle_s1);
end;
end;
Delphi-Quellcode:
procedure TMix_Player_f.Send_Message_Player_2(Sender: TObject);
var LHandle: Cardinal;
begin
fFileHandle_s2 := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, length(sendtext_2) + 1, 'Player2');
if fFileHandle_s2 <> 0 then
begin
FSpeicher := MapViewOfFile(fFileHandle_s2, FILE_MAP_WRITE, 0, 0, 0);
StrCopy(FSpeicher, PChar(sendtext_2));
LHandle := FindWindow('TMixPlayer_2_f', nil);
if LHandle <> 0 then
begin
SendMessage(LHandle, WM_USER + 2, 0, 0);
end;
CloseHandle(fFileHandle_s2);
end;
end;
Delphi-Quellcode:
procedure TMix_Player_f.FDatenEmpfang1(var AMessage: TMessage);
var LSpeicher: PChar;
LDest: String;
begin
fFileHandle_e1 := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, 500, 'Control1');
if fFileHandle_e1 <> 0 then
begin
LSpeicher := MapViewOfFile(fFileHandle_e1, FILE_MAP_WRITE, 0, 0, 0);
setlength(LDest, length(LSpeicher));
StrCopy(PChar(LDest), LSpeicher);
cometext1 := LDest;
workmessage1;
CloseHandle(fFileHandle_e1);
end;
end;
Delphi-Quellcode:
procedure TMix_Player_f.FDatenEmpfang2(var AMessage: TMessage);
var LSpeicher: PChar;
LDest: String;
begin
fFileHandle_e2 := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, 500, 'Control2');
if fFileHandle_e2 <> 0 then
begin
LSpeicher := MapViewOfFile(fFileHandle_e2, FILE_MAP_WRITE, 0, 0, 0);
setlength(LDest, length(LSpeicher));
StrCopy(PChar(LDest), LSpeicher);
cometext2 := LDest;
workmessage2;
CloseHandle(fFileHandle_e2);
end;
end;
Player1:
Delphi-Quellcode:
procedure TMixPlayer_1_f.Player_SendMessages(Sender: TObject);
var LHandle: Cardinal;
begin
fFileHandle_s1 := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, length(sendtext) + 1, 'Control1');
if fFileHandle_s1 <> 0 then
begin
FSpeicher := MapViewOfFile(fFileHandle_s1, FILE_MAP_WRITE, 0, 0, 0);
StrCopy(FSpeicher, PChar(sendtext));
LHandle := FindWindow('TMix_Player_f', nil);
if LHandle <> 0 then
begin
SendMessage(LHandle, WM_USER + 3, 0, 0);
end;
CloseHandle(fFileHandle_s1);
end;
end;
Delphi-Quellcode:
procedure TMixPlayer_1_f.FDatenEmpfang(var AMessage: TMessage);
var LSpeicher: PChar;
LDest: String;
begin
fFileHandle_e1 := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, 500, 'Player1');
if fFileHandle_e1 <> 0 then
begin
LSpeicher := MapViewOfFile(fFileHandle_e1, FILE_MAP_WRITE, 0, 0, 0);
setlength(LDest, length(LSpeicher));
StrCopy(PChar(LDest), LSpeicher);
cometext := LDest;
if checkbox1.Checked = true
then listbox1.items.append(LDest);
work_message;
CloseHandle(fFileHandle_e1);
end;
end;
Player2:
Delphi-Quellcode:
procedure TMixPlayer_2_f.Player_SendMessages(Sender: TObject);
var LHandle: Cardinal;
begin
fFileHandle_s1 := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, length(sendtext) + 1, 'Control2');
if fFileHandle_s1 <> 0 then
begin
FSpeicher := MapViewOfFile(fFileHandle_s1, FILE_MAP_WRITE, 0, 0, 0);
StrCopy(FSpeicher, PChar(sendtext));
LHandle := FindWindow('TMix_Player_f', nil);
if LHandle <> 0 then
begin
SendMessage(LHandle, WM_USER + 4, 0, 0);
end;
CloseHandle(fFileHandle_s1);
end;
end;
Delphi-Quellcode:
procedure TMixPlayer_2_f.FDatenEmpfang(var AMessage: TMessage);
var LSpeicher: PChar;
LDest: String;
begin
fFileHandle_e1 := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, 500, 'Player2');
if fFileHandle_e1 <> 0 then
begin
LSpeicher := MapViewOfFile(fFileHandle_e1, FILE_MAP_WRITE, 0, 0, 0);
setlength(LDest, length(LSpeicher));
StrCopy(PChar(LDest), LSpeicher);
cometext := LDest;
if checkbox1.Checked = true
then listbox1.items.append(LDest);
work_message;
CloseHandle(fFileHandle_e1);
end;
end;
|