![]() |
Array , Löschen von selben verhindern.
Wieder mein leidiges Array und pointer problem.
Delphi-Quellcode:
Beim erstellen des neuen Threads
Type
PWinampVisInfo = ^TWinampVisInfo; TWinampVisInfo = Packed record Title: PChar; FileName: PChar; PlaylistLength: integer; PlaylistPos: integer; Pos, Len: QWORD; VisHeader: PWinampVisHeader; VisModule: PWinampVisModule; Init, Init2, Rendering: boolean; DllInstance: THandle; WinHandle: THandle; PluginId: DWORD; ParentHandle: DWORD; Vis_Atom_Emu: ATOM; Vis_Window_Emu: HWND; VisInfoCount: Integer; end; Var VisInfo: array [1..5] of PWinampVisInfo;
Delphi-Quellcode:
Bleibt die Anwendung in der Function
ThreadHandle := BeginThread(nil, 0, @WinampVisWin, VisInfo[VisWinCounter], 0, ThreadId);
Delphi-Quellcode:
beim ersten begin stehen und gibt ein AV aus.
function WinampVisWin(VisInfo : array of PWinampVisInfo): HWND;
Was ist in der Functionszeile verkehrt? gruß |
Re: Array , Löschen von selben verhindern.
Hat sich erst mal erledigt!
Delphi-Quellcode:
gruß
function WinampVisWin: HWND;
|
Re: Array , Löschen von selben verhindern.
PUSH.. :duck:
Array wird überschrieben bzw.. gelöscht.
Delphi-Quellcode:
Solange wie nur ein Plugin gestartet wird läuft alles rund
try
GetMem(VisInfo[VisCounter], SizeOf(TWinampVisInfo)); ZeroMemory(VisInfo[VisCounter], SizeOf(TWinampVisInfo)); except BassFuncs^.SetError(BASS_ERROR_MEM); Exit; end; wenn zwei laufen bekomme ich beim beenden immer einen AV. Habe es mit ReAllocMem versucht aber irgendwie wird das 1 Plugin mit dem zweiten überschrieben Bedeutet habe nun zwei index einträge mit den gleichen Plugineigenschaften. Hmmm ... Ka warum. gruß |
Re: Array , Löschen von selben verhindern.
Pushen ist erst nach 24 stunden erlaubt :warn: :zwinker:
Edit: Ich meine da einen Fehler mit den PChar Pointern zu sehen, aber da ich mir nicht sicher bin, bzw. die Lösung nicht weiß, sag ich lieber nix, es könnte nicht stimmten... |
Re: Array , Löschen von selben verhindern.
Zitat:
Denke das problem liegt daran das ich das array nicht redimensioniere (ReAllocMem) Weis nicht wo oder wie ich da am besten ansetzen soll. Meine Versuche gingen komplett daneben. Alles funktioniert solange kein zweites plugin zur gleichen zeit aufgerufen wurde. gruß |
Re: Array , Löschen von selben verhindern.
Ich sagte ja, ich bin mir nicht sicher :wink:
Und es stimmt nicht :pale: Ich hab das Problem nachgestellt, aber mir ist es nicht gelungen, das das ganze Array gelöscht wurde. |
Re: Array , Löschen von selben verhindern.
Liste der Anhänge anzeigen (Anzahl: 2)
Zitat:
Es wird überschrieben .. Quasi befindet sich dann das zweite Plugin in beiden Arrays.. Deshalb bekomme ich dann beim beenden den AV. Schau die pics der reihe nach dann weißt du was ich meine. gruß |
Re: Array , Löschen von selben verhindern.
Äh ja, das meinte ich eigentlich mit "gelöscht".
Bist Du Dir sicher, das der VisCounter richtig gesteuert wird bzw. das es an der Programmstelle hakt? Sonst fällt mir leider nix mehr dazu ein :gruebel: |
Re: Array , Löschen von selben verhindern.
Zitat:
Na ok Danke. Dann weiss ich auch nicht weiter :wall: gruß |
Re: Array , Löschen von selben verhindern.
Das erste was mir auffiel ist das du ein dynamsiches Array übergibst was aber delphispezifisch ist. Ich kann mir nicht vorstellen das Winamp ein Delphiarray erwartet.
|
Re: Array , Löschen von selben verhindern.
Zitat:
Lediglich der Header und das Modul welche sich in PWinampVisInfo befindet werden aus dem Plugin geladen
Delphi-Quellcode:
aber auch diese haben nichts mit Winamp zu tun.VisHeader: PWinampVisHeader; VisModule: PWinampVisModule; Das Array selbst ist Privat. Gruß |
Re: Array , Löschen von selben verhindern.
Guten Morgen Emil,
eines ist sicher: der Fehler steckt nicht in den vier Zeilen Code, die du gezeigt hast. Mit denen forderst du nur Speicher an und initialisierst ihn. Interessanter ist dein Code, mit dem du nach dem Löschen eines Eintrags die nachfolgenden Einträge verschiebst. Eventuell wird dabei der Counter nicht rechtzeitig dekrementiert - oder garnicht?. Freundliche Grüße von Domstadt zu Domstadt |
DP-Maintenance
Dieses Thema wurde von "alcaeus" von "Programmieren allgemein" nach "Sonstige Fragen zu Delphi" verschoben.
|
Re: Array , Löschen von selben verhindern.
Zitat:
Ja .. das ist mein problem das redimensionieren (verschieben) der Einträge. Habe es mit ReAllocMem versucht und keinen Erfolg gehabt.
Delphi-Quellcode:
Wie schon gesagt es funktioniert alles (und ist keine übersetzung) von einer anderen Quelle
function BASS_WINAMPVIS_CreateVis(f: PChar; module, flags: DWORD; AppHandle: DWORD; AppHDC: boolean; VisCounter: integer): HVIS; stdcall;
var mbi: MEMORY_BASIC_INFORMATION; winampVisGetHeader: function: PWinampVisHeader; cdecl; begin Result := 0; // Winamp Emulator Fenster HWND VisDllHandle := 0; // Wenn True Plugin in der Applikation // oder eigenen Skin visualisieren AppParenthDC := AppHDC; // Voller Pfad des Plugin FileName := StrPas(f); // HWND von der ausführenden Application AppParentHandle := AppHandle; if (not FileExists(PChar(FileName))) then begin BassFuncs^.SetError(BASS_ERROR_FILEOPEN); Exit; end; if VisCounter = 0 then VisWinCounter := VisCounter; try GetMem(VisInfo[VisCounter], SizeOf(TWinampVisInfo)); ZeroMemory(VisInfo[VisCounter], SizeOf(TWinampVisInfo)); except BassFuncs^.SetError(BASS_ERROR_MEM); Exit; end; try SetCurrentDirectory(PChar(FileName)); VisDllHandle := LoadLibrary(PChar(FileName)); except if (VisDllHandle <> 0) then FreeLibrary(VisDllHandle); FreeMem(VisInfo[VisCounter]); BassFuncs^.SetError(BASS_ERROR_START); Exit; end; if (VisDllHandle = 0) then begin FreeMem(VisInfo[VisCounter]); BassFuncs^.SetError(BASS_ERROR_START); Exit; end; @winampVisGetHeader := GetProcAddress(VisDllHandle, 'winampVisGetHeader'); if (@winampVisGetHeader = nil) then begin FreeLibrary(VisDllHandle); FreeMem(VisInfo[VisCounter]); BassFuncs^.SetError(BASS_ERROR_HANDLE); Exit; end; VisInfo[VisCounter]^.VisHeader := winampVisGetHeader; if (VisInfo[VisCounter]^.VisHeader = nil) then begin FreeLibrary(VisDllHandle); FreeMem(VisInfo[VisCounter]); BassFuncs^.SetError(BASS_ERROR_START); Exit; end; VisInfo[VisCounter]^.VisModule := VisInfo[VisCounter]^.VisHeader^.getModule(module); if (VisInfo[VisCounter]^.VisModule = nil) then begin FreeLibrary(VisDllHandle); FreeMem(VisInfo[VisCounter]); BassFuncs^.SetError(BASS_ERROR_START); Exit; end; // Überprüfe ob eine neue Instanz erstellt werden soll VisInfo[VisCounter]^.Init := ((flags and BASS_VIS_NOINIT) <> BASS_VIS_NOINIT); VisInfo[VisCounter]^.DllInstance := VisDllHandle; if (VisInfo[VisCounter]^.Init) then begin VisWinCounter := VisCounter; VisInfo[VisWinCounter]^.VisInfoCount := VisWinCounter; // Neuen Thread erstellen ThreadHandle := BeginThread(nil, 0, @WinampVisWin, VisInfo[VisWinCounter], 0, ThreadId); // DLL aus Speicher entfernen wenn ThreadHandle = 0 if (ThreadHandle = 0) then begin FreeLibrary(VisDllHandle); FreeMem(VisInfo[VisWinCounter]); BassFuncs^.SetError(BASS_ERROR_INIT); Exit; end; // Thread schließen CloseHandle(ThreadHandle); end; VirtualQuery(VisInfo[VisCounter]^.VisHeader.description, mbi, SizeOf(MEMORY_BASIC_INFORMATION)); VisInfo[VisCounter]^.PluginId := DWORD(mbi.AllocationBase); W_AppendHandle(DWORD(VisInfo[VisCounter])); BassFuncs^.SetError(BASS_OK); Result := DWORD(VisInfo[VisCounter]); end; Hier
Delphi-Quellcode:
müßte der speicher verschoben werden wenn VisCounter > 1 daran bin ich gescheitert.
try
GetMem(VisInfo[VisCounter], SizeOf(TWinampVisInfo)); ZeroMemory(VisInfo[VisCounter], SizeOf(TWinampVisInfo)); except BassFuncs^.SetError(BASS_ERROR_MEM); Exit; end; EDIT: Zitat:
Der Counter bzw.. das plugin was entladen weden soll wird aus der Hauptanwendung übergeben.
Delphi-Quellcode:
gruß
function BASS_WINAMPVIS_Free(handle: HVIS; VisCounter: Integer): boolean; stdcall;
begin Result := False; VisWinCounter := VisCounter; if (not W_ValidHandle(handle)) then begin BassFuncs^.SetError(BASS_ERROR_HANDLE); Exit; end; VisInfo[VisCounter] := PWinampVisInfo(handle); if (VisInfo[VisCounter]^.Init) then begin PostMessage(VisInfo[VisCounter]^.WinHandle, WM_QUIT, 0, 0); FreeLibrary(VisDllHandle); end else begin W_RemoveHandle(DWORD(VisInfo[VisCounter])); FreeLibrary(VisInfo[VisCounter]^.DllInstance); FreeMem(VisInfo[VisCounter]); end; BassFuncs^.SetError(BASS_OK); Result := True; end; |
Re: Array , Löschen von selben verhindern.
Hallo Emil,
Delphi-Quellcode:
das muss nicht sein. In der Regel weiß Delphi zwischen PChar und String automatisch zu konvertieren.
// Voller Pfad des Plugin
FileName := StrPas(f);
Delphi-Quellcode:
f oder FileName genügt - kein casting nötig.
if not FileExists(PChar(FileName)) then
Delphi-Quellcode:
das ist nicht verständlich - auch weil du so viele globale Variablen benutzt.
if VisCounter = 0 then
VisWinCounter := VisCounter;
Delphi-Quellcode:
Wenn VisInfo als statisches Array deklariert ist (siehe Beitrag #1), dann greift der Code hier bei VisCounter = 0 ins Leere.
try
GetMem(VisInfo[VisCounter], SizeOf(TWinampVisInfo)); ZeroMemory(VisInfo[VisCounter], SizeOf(TWinampVisInfo)); except BassFuncs^.SetError(BASS_ERROR_MEM); Exit; end; Kannst du nicht ein dynamisches Array verwenden?
Delphi-Quellcode:
An die Stelle der globalen Variable VisCounter könnte dann Length(VisInfo) treten. Wenn du ein statisches Array benutzen musst, dann müsstest du aber ähnlich vorgehen.
type
TVisInfo = array of PWinampVisInfo; var VisInfo: TVisInfo; function AddVisInfo(var vi: TVisInfo): TVisInfo; begin index := Length(vi); SetLength(vi, Succ(index)); New(vi[index]); // Freigabe mit Dispose(vi[index]) - Borland empfiehlt es ZeroMemory(vi[index], SizeOf(vi[index]^)); end; procedure DeleteVisInfo(var vi: TVisInfo; p: PWinampVisInfo); var index, iFound: Integer; begin // locate pointer iFound := -1; // not found for index := Low(vi) to Length(vi) do if (index < Length(vi)) and (vi[index] = p) then begin iFound := index; Break; end; if iFound <> -1 then // fill the gap begin Dispose(vi[index]); if index <> High(vi) then vi[index] := vi[High(vi)]; SetLength(vi, High(vi)); end; end;
Delphi-Quellcode:
Jetzt muss ich erstmal eine Pause machen - deine Probleme sind immer so umfangreich...
// ...
// SetCurrentDirectory(PChar(FileName)); // vielleicht besser so: SetCurrentDirectory(ExtractFilePath(f)); Freundliche Grüße |
Re: Array , Löschen von selben verhindern.
Zitat:
VisCounter = 0 ist reserviert für Plugins welche nicht initialisiert(gestartet) wurden. VisWinCounter ist der zähler welcher übergreifend im ganzen Code zur identifizierung des in der PluginListe angeklickten Plugin gilt. Wurde das Plugin nicht gestartet dann ist VisWinCounter immer null. Muss also wie oben den wert 0 bekommen. Dadurch kann ich die configuration der Plugins starten editieren welche selbst nicht initialisiert(gestartet) wurden.
Code:
Hier wird aus der Hauptanwendung tmpvis ermittelt.
tmpvis = BASS_WINAMPVIS_CreateVis(alist(IntI), module, BASS_VIS_NOINIT, 0, False, "0")
BASS_VIS_NOINIT bedeutet das das Plugin nicht gestartet wird deshalb wird VisCounter mit 0 übergeben. Nun kann ich alle namen der module und des Plugins selbst ermitteln ohne das ein Plugin gestartet wurde. VisCounter = 0 geht also nie ins leere .. Wenn 0 dann kann ich mit allen Plugins arbeiten .. config usw.. ohne das die gestarteten Plugins davon betroffen oder beeinflusst werden. VisWinCounter wird zweimal übergeben einmal 0 wenn kein Plugin gestartet wird und hier
Delphi-Quellcode:
wenn eins gestartet wurde. erst dann wird es hochgezählt.
if (VisInfo[VisCounter]^.Init) then
begin VisWinCounter := VisCounter; VisInfo[VisWinCounter]^.VisInfoCount := VisWinCounter; Zitat:
Bin halt übervorsichtig :) Also beim ersten start 1 Plugin läuft gibt es keinen AV keine anderen Fehler! Beim zweiten Plugin muss ich nur dafür sorgen das der erste eintrag Array(1) nicht von Array(2) überschrieben wird. Andere probs habe ich nicht. gruß |
Re: Array , Löschen von selben verhindern.
Niemand eine Ahnung?
Es muss doch möglich sein ähnlich wie dieser Code (funktioniert nicht ganz)
Delphi-Quellcode:
im Array(2) die Daten vom 2 plugin zu integrieren.
if VisCounter = 0 then
begin VisWinCounter := VisCounter; try GetMem(VisInfo[VisCounter], SizeOf(TWinampVisInfo)); ZeroMemory(VisInfo[VisCounter], SizeOf(TWinampVisInfo)); except BassFuncs^.SetError(BASS_ERROR_MEM); Exit; end; end else begin ReAllocMem(VisInfo[VisCounter], VisCounter * SizeOf(TWinampVisInfo)); end; ohne das Array(1) Daten vom 1 Plugin überschrieben oder gelöscht werden. gruß |
Re: Array , Löschen von selben verhindern.
Das Array ist ein Array of Pxxxxx, Und Du initialisierst jedes Element, in dem Du SizeOf(Txxxxx) Bytes überschreibst.....
Jedes Element des Arrays enthält doch aber nur SizeOF (Pxxxxx) Bytes, oder? |
Re: Array , Löschen von selben verhindern.
Zitat:
zum ersten ja! Nochmal die Type welche als Array ausgelegt ist.
Delphi-Quellcode:
so wie in meinen letzten Beispiel müßte es eigentlich gehen was noch fehlt wäre
Type
PWinampVisInfo = ^TWinampVisInfo; TWinampVisInfo = Packed record Title: PChar; FileName: PChar; PlaylistLength: integer; PlaylistPos: integer; Pos, Len: QWORD; VisHeader: PWinampVisHeader; VisModule: PWinampVisModule; Init, Init2, Rendering: boolean; DllInstance: THandle; WinHandle: THandle; PluginId: DWORD; ParentHandle: DWORD; Vis_Atom_Emu: ATOM; Vis_Window_Emu: HWND; VisInfoCount: Integer; end; Var VisInfo: array [1..5] of PWinampVisInfo; Das Array(1) zu kopieren wenn ein neues Plugin gestartet wird Das Array(2) mit den Daten vom Plugin 2 zu füllen und die kopierten Daten von Array(1) zurück zuschreiben wenn dieses überschrieben wird.(das wird es ja... mein Problem!) Weiss sonst nicht wie ich das erklären soll. gruß |
Re: Array , Löschen von selben verhindern.
Zitat:
Edit: Also wenn's echt nur ums kopieren geht: CopyMemory EDit²: Die fehlenden roten Kasten können einem ganz schön durcheinander bringen :roteyes: |
Re: Array , Löschen von selben verhindern.
Zitat:
Es können ja bis zu 5 Plugins gleichzeitig gestartet werden Wie soll das gehen mit dem hin und her kopieren ? Zitat:
gruß |
Re: Array , Löschen von selben verhindern.
Zitat:
Zitat:
Diese Beiträge sind dann unten rot dargestellt. Aus irgendeinem Grund funken die bei mir zu 90% nicht (vielleicht Modem zu langsam), so kommt man leicht durcheinander. |
Re: Array , Löschen von selben verhindern.
Hmm Ich verstehe den Kram echt nicht!
Habe es jetzt ein paarmal gestartet einmal gehts dann wieder nicht. Und das ohne das etwas am Source verändert wurde. Scheint irgendein Timing problem zu sein oder sonstwas ..
Delphi-Quellcode:
if (VisInfo[VisCounter]^.Init) then
begin VisWinCounter := VisCounter; VisInfo[VisWinCounter]^.VisInfoCount := VisWinCounter; if assigned(VisInfo[VisCounter]) then begin ReAllocMem(VisInfo[VisCounter], VisCounter * SizeOf(TWinampVisInfo)); end; // Neuen Thread erstellen ThreadHandle := BeginThread(nil, 0, @WinampVisWin, VisInfo[VisWinCounter], 0, ThreadId); Zitat:
Aber das löst mein Problem nicht wie ich CopyMemory benutzen muss ist mir bekannt :) gruß |
Re: Array , Löschen von selben verhindern.
Hast Du lokale Variablen?
Bzw. hat der Thread genug Zeit zum Starten? Das wäre eine Erklärung für das Verhalten. (Muss aber nicht sein :zwinker: ) Ich verstehe zwar nicht warum, aber es war ja nur ne Idee mit CopyMemory... |
Re: Array , Löschen von selben verhindern.
Zitat:
Und der zweite Thread (2 Plugin) wird erst dann gestartet wenn der Speicher neu Dimensioniert wurde und das Array(2) mit neuen Daten gefüllt ist, die sind einmal richtig dann wieder nicht. Zitat:
da er nur manchmal auftritt :? Zitat:
Mal läuft es mal nicht. :wall: gruß |
Re: Array , Löschen von selben verhindern.
(CopyMemory) Jetzt hab' ich's kapiert :mrgreen:
Zitat:
|
Re: Array , Löschen von selben verhindern.
Zitat:
Damit würde ich verhindern das die class Winamp v1.x rechtzeitig erstellt wird. Dann geht gar nichts mehr. gruß |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:01 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