Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Dynamisches Array oder Klasse als Array auslegen (https://www.delphipraxis.net/77666-dynamisches-array-oder-klasse-als-array-auslegen.html)

EWeiss 22. Sep 2006 18:59


Dynamisches Array oder Klasse als Array auslegen
 
Hallo

Habe ein kleines Problem bei der übersetzung eines C++ QuellTextes

Code:
WINAMPPLUGINPROPDSP **winampDSP = NULL;
Diese zeile erzeugt ein dynamisches array welches ich in Delphi übersetzen muss.

Es ist ein Speicherbereich, in dem hintereinander Pointer auf
Insanzen vom Typ: WINAMPPLUGINPROPDSP
Gespeichert werden.

Die Instanz ist von folgenden Typ!
Code:
typedef struct WINAMPPLUGINPROP_TAG_DSP
{
...
} WINAMPPLUGINPROPDSP;
Meine Frage!
Ist es möglich ein Klasse von vornherein als array auszulegen?
welche beide variationen aktzeptieren muss..
Beispiel:
Delphi-Quellcode:
winampDsp := winampDSP[a];
winampDSP[a] := winampDsp;
Oder sollte diese dynamisch ausgelegt werden.

Wenn ja wie geht das in Delphi ?

Noch eine Frage zu den Thema.
auch hier habe ich ein Problem.

Delphi-Quellcode:
Var
   winampDsp: PWinampDSPInfo;
  a: integer;
  i, s: Short;

         begin
            // 16-bit already, just need to copy
            i := Trunc(buffer);
            s := (short(AllocMem(length *2 )));      // alloc twice as much as needed, since modify might return more
            for a := 0 to (Trunc(length /2)) do
            begin;
//               s[a]=i[a];
            end;

i,s ist nicht als array ausgelegt.
Wie bekomme ich es dennoch zum laufen ?

Gruß

marabu 22. Sep 2006 20:05

Re: Dynamisches Array oder Klasse als Array auslegen
 
Hallo,

Zitat:

Zitat von EWeiss
Code:
WINAMPPLUGINPROPDSP **winampDSP = NULL;
Diese zeile erzeugt ein dynamisches array welches ich in Delphi übersetzen muss.

es wird hier nur ein typisierter Zeiger deklariert und mit NULL initialisiert, wenn ich nicht irre.

Zitat:

Zitat von EWeiss
Es ist ein Speicherbereich, in dem hintereinander Pointer auf
Insanzen vom Typ: WINAMPPLUGINPROPDSP
Gespeichert werden.

Hier bin ich mit dir einer Meinung.

Der Zugriff kann über Zeiger-Arithmetik erfolgen oder durch Überlagerung des Speicherbereiches mit einem Array. Vielleicht verhilft dir ein wenig Code zur Erkenntnis?

Delphi-Quellcode:
type
  WINAMPPLUGINPROPDSP = record
    // ...
  end;
  PWinAmpPluginPropDSP = ^WINAMPPLUGINPROPDSP;
  PPWinAmpPluginPropDSP = ^PWinAmpPluginPropDSP;

var
  WinAmpDSP = PPWinAmpPluginPropDSP;

// access using pointer arithmetic and nil indicating end of list
var
  p: PWinAmpPluginPropDSP;
begin
  p := WinAmpDSP^;
  while Assigned(p) do
  begin
    // ShowMessage(p^.anyStringMember)
    Inc(p);
  end;
end;


// access using array overlay and count indicating end of list
type
  TA: array [0..0] of PWinAmpPluginPropDSP;
var
  pa: ^TA;
  count: Integer;
begin
  // ...
  pa := WinAmpDSP;
  for i := 0 to Pred(dspCount) do
    // ShowMessage(pa[i]^.anyStringMember) ;
end;
Getippt und nicht getestet.

Grüße vom marabu

EWeiss 22. Sep 2006 20:37

Re: Dynamisches Array oder Klasse als Array auslegen
 
Danke marabu.

Werde mir das mal zu gemüte führen..
Anbei nochmal die ganze klasse (Delphi style angepasst)

Delphi-Quellcode:
Type
  //WinampDSPInfo Klasse
  PWinampDSPInfo = ^TWinampDSPInfo;
  TWinampDSPInfo  = record
     csH                      : TRTLCriticalSection;          // CRITICAL_SECTION
     handle                   : DWORD;                                // DSP handle
     NumberOfModules          : UINT;                                  // number of modules in the dsp
     hDll                     : HWND;                                // the dll instance
     pModule                  : PWinampDSPHeader;                 // module header
     pDSP                     :   PWinampDSPModule;                 // current selected dsp module
     hchannel                 : DWORD;                                // channel associated to dsp
    module                   : DWORD;                                // curent selected dsp module
     hdsp                     : HDSP;                                   // optional dsp handle
     DSP_Window_Emu           : HWND;                               // related fake window handle
     DSP_Atom_Emu             : ATOM;                                 // related fake window atom
     songTitle                : array[0..MAX_PATH-1] of char;                        // the playing song title
     fileName                 : array[0..MAX_PATH-1] of char;                        // the playing file name
     info                     : BASS_CHANNELINFO;                 // channel info
  end;
Delphi-Quellcode:
implementation

var
 winampDSP : PWinampDSPInfo = nil;
Der sinn des arrays liegt darin das bei jeden aufruf eines neuen DSP Plugins
eine neue Instanz von winampDSP gebildet werden soll das geschieht hier.

Original
Code:
void AddDSP(WINAMPPLUGINPROPDSP *winampDsp)
{
   DWORD a;
   for (a=0;a<winampDSPcounter;a++)
        if (!winampDSP[a]) break;

   if (a==winampDSPcounter)
   { 
      // no empty slot, so add a new one
      winampDSP = (WINAMPPLUGINPROPDSP**)realloc(winampDSP, (winampDSPcounter+1)*sizeof(WINAMPPLUGINPROPDSP*));
      winampDSPcounter++;
   }
   winampDsp->handle = ++winampDSPhandle;
   // insert the new Winamp DSP
   winampDSP[a] = winampDsp;
}
Übersetzt
Delphi-Quellcode:
procedure AddDSP(winampDsp: PWinampDSPInfo);
var
  a: DWORD;

begin
   for a := 0 to winampDSPcounter do
        if (not winampDSP[a]) then break;

   if a = winampDSPcounter then
   Begin
      // no empty slot, so add a new one
//    winampDSP := ReallocMem(winampDSP, (winampDSPcounter + 1) SizeOf(PWinampDSPInfo);
      winampDSPcounter;
   end;
   winampDsp^.handle := winampDSPhandle;
   // insert the new Winamp DSP
//  winampDSP[a] := winampDsp;
end;
Hier sind meine beiden Probleme.
ReallocMem ärger bei 'SizeOf'
und halt das berüchtigte array winampDSP[a] := winampDsp;

Vielleicht kannst ja mal drüberfliegen was da nicht in Ordnung ist.

gruß

marabu 22. Sep 2006 21:07

Re: Dynamisches Array oder Klasse als Array auslegen
 
Deine Umsetzung ist nicht korrekt. Insbesondere sind winampDsp und winampDSP nicht das gleiche. Hoffentlich bist du nicht schon an anderen Stellen in diese Falle getappt.

Delphi-Quellcode:
procedure AddDSP(dsp: PWinampDSPInfo);
type
  TDspPtrArray = array [0..0] of PWinampPluginPropDSP;
  PDspPtrArray = ^TDspPtrArray;
var
  i: DWORD;
  winampDSP: PDspPtrArray;
begin
  for i := 0 to winampDSPcounter do
    if not Assigned(winampDSP^[i]) then
      Break;
 
  if i = winampDSPcounter then
  begin
    // no empty slot, so add a new one
    winampDSP := ReallocMem(winampDSP, i * SizeOf(PWinampDSPInfo));
    Inc(winampDSPcounter);
  end;
  dsp^.handle := winampDSPhandle;
  // insert the new Winamp DSP
  winampDSP^[i] := dsp;
end;
Wieder ohne Garantie.

marabu

EWeiss 22. Sep 2006 21:15

Re: Dynamisches Array oder Klasse als Array auslegen
 
Zitat:

Deine Umsetzung ist nicht korrekt. Insbesondere sind winampDsp und winampDSP nicht das gleiche. Hoffentlich bist du nicht schon an anderen Stellen in diese Falle getappt.
Hmmm ... Ich denke doch!
beim auskommentieren der kritischen stellen habe ich die DLL erstellen können
bekomme allerdings in der ersten LOAD-Funktion schon einen fatal crash
wird wohl alles damit zusammen hängen.

Ich werde deine Funktion mal testen und mit anderen vergleichen.

Danke!.

Ein kleines problem tritt in deiner Funktion noch auf.

Delphi-Quellcode:
winampDSP := ReallocMem(winampDSP, i * SizeOf(PWinampDSPInfo));
[Pascal Error] BassWaDSP.pas(119): E2010 Incompatible types: 'PDspPtrArray' and 'procedure, untyped pointer or untyped parameter'

Gruß

EWeiss 23. Sep 2006 02:49

Re: Dynamisches Array oder Klasse als Array auslegen
 
Habe mich nun stundenlang mit der einen zeile beschäftigt

Delphi-Quellcode:
winampDSP := ReallocMem(winampDSP, i * SizeOf(PWinampDSPInfo));
bekomme immer noch den Fehler!
Zitat:

[Pascal Error] BassWaDSP.pas(119): E2010 Incompatible types: 'PDspPtrArray' and 'procedure, untyped pointer or untyped parameter'
Gruß ..

Der_Unwissende 23. Sep 2006 09:26

Re: Dynamisches Array oder Klasse als Array auslegen
 
Zitat:

Zitat von EWeiss
Habe mich nun stundenlang mit der einen zeile beschäftigt

Delphi-Quellcode:
winampDSP := ReallocMem(winampDSP, i * SizeOf(PWinampDSPInfo));
bekomme immer noch den Fehler!

Dann schau einfach in die Hilfe und erkenne dass ReallocMem eine procedure ist, das winampDSP wird hier als referenz oder Call-by-value-result übergeben, jedenfalls schon geschrieben, lass also die Zuweisung davor weg.

Gruß Der Unwissende

EWeiss 23. Sep 2006 15:49

Re: Dynamisches Array oder Klasse als Array auslegen
 
Zitat:

Zitat von Der_Unwissende
Zitat:

Zitat von EWeiss
Habe mich nun stundenlang mit der einen zeile beschäftigt

Delphi-Quellcode:
winampDSP := ReallocMem(winampDSP, i * SizeOf(PWinampDSPInfo));
bekomme immer noch den Fehler!

Dann schau einfach in die Hilfe und erkenne dass ReallocMem eine procedure ist, das winampDSP wird hier als referenz oder Call-by-value-result übergeben, jedenfalls schon geschrieben, lass also die Zuweisung davor weg.

Gruß Der Unwissende

In C++ scheint es zu funktionieren na gut.
Super das wars ;)

Ich hätte noch viele fragen
aber erst mal die eine.

Wenn ich in VB eine Variable Deklariere dann gilt diese solange wie der Thread besteht.
Hier in Delphi stelle ich fest das obwohl sie Deklariert ist immer ein Hinweis
kommt sie wäre nicht initialisiert.

Reicht es nicht wenn sich diese als Public Decariert im Header befindet?

Delphi-Quellcode:
procedure AddDSP(winampDSP: PWinampDSPInfo);

var
  a: DWORD;
  DspPtrArray : PDspPtrArray;
begin

  for a := 0 to winampDSPcounter do
    if not Assigned(DspPtrArray^[a]) then
      Break;

  if a = winampDSPcounter then
  begin
    // no empty slot, so add a new one
    ReallocMem(winampDSP, a * SizeOf(PWinampDSPInfo));
    Inc(winampDSPcounter);
  end;
  winampDSP^.handle := winampDSPhandle;
  // insert the new Winamp DSP
  DspPtrArray^[a] := winampDSP;
end;
Zitat:

[Pascal Warning] BassWaDSP.pas(94): W1036 Variable 'DspPtrArray' might not have been initialized
Wie und warum muss ich diese jedesmal neu initialisieren.
Was müßte ich übergeben damit sie intitalisiert wird?

Delphi-Quellcode:
DspPtrArray^[a] := nil;
würde ja die Daten die sich im Array befinden löschen.

gruss

marabu 23. Sep 2006 16:30

Re: Dynamisches Array oder Klasse als Array auslegen
 
Du musst diesen Zeiger tatsächlich vor seiner ersten Verwendung initialisieren, indem du ihm den Wert des Zeigers winampDSP (so war der Name der globalen Variablen im C++ Code) zuweist. Nur so wird schließlich die Redefinition des Speicherbereichs erreicht, damit du über array[index] zugreifen kannst.

marabu

EWeiss 23. Sep 2006 17:36

Re: Dynamisches Array oder Klasse als Array auslegen
 
Zitat:

Zitat von marabu
Du musst diesen Zeiger tatsächlich vor seiner ersten Verwendung initialisieren, indem du ihm den Wert des Zeigers winampDSP (so war der Name der globalen Variablen im C++ Code) zuweist. Nur so wird schließlich die Redefinition des Speicherbereichs erreicht, damit du über array[index] zugreifen kannst.

marabu

Delphi-Quellcode:
procedure AddDSP(winampDSP: PWinampDSPInfo);

var
  a: DWORD;

begin

  a := 0;
  DspPtrArray^[a] := winampDSP;

  for a := 0 to winampDSPcounter do
    if not Assigned(DspPtrArray^[a]) then
      Break;

  if a = winampDSPcounter then
  begin
    // Array nicht leer, füge ein neues hinzu
    ReallocMem(winampDSP, a * SizeOf(PWinampDSPInfo));
    Inc(winampDSPcounter);
  end;
  winampDSP^.handle := winampDSPhandle;
  // addiere ein Winamp DSP Plugin zum Array
  DspPtrArray^[a] := winampDSP;
end;
wäre es so richtig?
Zumindest kommt kein fehler mehr.

Eine Frage nebenbei.
Kann ich hier im Thread weiter machen oder muss ich für jede Frage einen neuen aufmachen?

gruß ..

marabu 23. Sep 2006 17:52

Re: Dynamisches Array oder Klasse als Array auslegen
 
Eher so:

Delphi-Quellcode:
begin
  DspPtrArray := gWinampDSP; // natürlich die globale Variable !!
  // ...
end;
Ich weiß nicht wie du den Namenskonflikt aufgelöst hast.

Zitat:

Zitat von EWeiss
kann ich hier im Thread weiter machen oder muss ich für jede Frage einen neuen aufmachen?

Ich persönlich glaube, dass eine Abtrennung momentan keinen Sinn macht, da sich momentan alles um die Portierung einer bestimmten Prozedur dreht. Sobald du das Gefühl hast den Schwerpunkt des Themas zu verlagern mache einen neuen thread auf.

Grüße

marabu

EWeiss 23. Sep 2006 18:20

Re: Dynamisches Array oder Klasse als Array auslegen
 
Delphi-Quellcode:
begin
  DspPtrArray := gWinampDSP; // natürlich die globale Variable !! 
  // ...
end;
Verstehe ich jetzt nicht.
Meine Globalen variablen sind diese.

Muss ich jetzt noch eine hinzufügen um die Variable DspPtrArray zu initialisieren?
Sorry für die vielleicht dumme Frage muss mich erst mal darin einarbeiten.

Neue Sprache schwere Sprache :wink:

Delphi-Quellcode:
implementation

var
 winampDSPcounter : DWORD   = 0;
 winampDSPhandle : DWORD   = 0;
 PlayState       : DWORD;
 DspPtrArray     : PDspPtrArray = nil;
 winampDSP       : PWinampDSPInfo;
 pGetMod         : PWinampDSPHeader;
gruß

marabu 23. Sep 2006 18:37

Re: Dynamisches Array oder Klasse als Array auslegen
 
Du hattest in deinem Eröffnungsbeitrag aus dem C++ Code zitiert:

Code:
WINAMPPLUGINPROPDSP **winampDSP = NULL;
Wenn du den Namen für deine globale Variable in Object Pascal beibehalten willst, dann so:

Delphi-Quellcode:
var
  winampDSP: PPWinAmpPluginPropDSP; // siehe Beitrag #2
Allerdings darf dann der Parameter der Prozedur nicht winampDSP heißen, da die C++ Bezeichner wegen der case sensitivity nicht 1:1 nach Object Pascal übertragen werden können:

Delphi-Quellcode:
procedure AddDSP(dsp: PWinampDSPInfo);
var
  a: DWORD;
begin
  DspPtrArray := winampDSP;
  // ...
  DspPtrArray^[a] := dsp;
marabu

EWeiss 23. Sep 2006 18:45

Re: Dynamisches Array oder Klasse als Array auslegen
 
Leider ist jetzt alles etwas durcheinander geraten!
Dürfte ich dir den aktuellen stand( Quelltext) zuschicken?

Soll nicht heißen das du daran arbeiten sollst.
So könntest du dir aber ein aktuelleres Bild von den Fortschritt machen

Die Variablen aus dem c++ Code sind nicht mehr identisch mit dem in Delphi
da ich der übersicht wegen doch lieber Hausgemachte Delphi Variablen verwenden möchte.

gruß

marabu 23. Sep 2006 19:39

Re: Dynamisches Array oder Klasse als Array auslegen
 
Zitat:

Zitat von EWeiss
Dürfte ich dir den aktuellen stand( Quelltext) zuschicken?

Wenn du den Quelltext nur mir zuschickst, dann übst du moralischen Druck auf mich aus und ich muss dich vielleicht trotzdem enttäuschen. Stelle den Quelltext doch in diesen thread ein - dann können dir auch andere helfen, falls ich überraschend verscheide oder meine Frau mir mit dem Baseballschläger den Zugang zum PC verwehrt. Ist das ein deal?

Freundliche Grüße

marabu

PS: So ein fortschrittliches Seniorenheim - mit Internetzugang ...

EWeiss 23. Sep 2006 20:20

Re: Dynamisches Array oder Klasse als Array auslegen
 
Zitat:

Zitat von marabu
Zitat:

Zitat von EWeiss
Dürfte ich dir den aktuellen stand( Quelltext) zuschicken?

Wenn du den Quelltext nur mir zuschickst, dann übst du moralischen Druck auf mich aus und ich muss dich vielleicht trotzdem enttäuschen. Stelle den Quelltext doch in diesen thread ein - dann können dir auch andere helfen, falls ich überraschend verscheide oder meine Frau mir mit dem Baseballschläger den Zugang zum PC verwehrt. Ist das ein deal?

Freundliche Grüße

marabu

PS: So ein fortschrittliches Seniorenheim - mit Internetzugang ...

Wäre kein Problem was den Delphi Quelltext angeht.
Beim C++ Quelltext sieht das anders aus.

Muss mich erst informieren ob ich das darf.. Will den Author nicht übergehen ;)

Auch Freundliche grüße.

EWeiss 24. Sep 2006 08:18

Re: Dynamisches Array oder Klasse als Array auslegen
 
Bin immer noch in der procedure

Delphi-Quellcode:
procedure AddDSP(winampDsp: WINAMPPLUGINPROPDSP); stdcall;
dort befindet sich im Original die Zeile
Code:
winampDsp->handle = ++winampDSPhandle;
Habe gelesen das ++ das gleiche sein soll wie Inc()

als Präfix-Operator:
++i;

inc(i); oder i:= i + 1;

Das winampDsp^.handle hat den wert 50 würde also wenn ich das so umsetze den Wert 1 bekommen
Das scheint mir aber irgenwie nicht das richtige zu sein.

gruß ,..

marabu 24. Sep 2006 09:13

Re: Dynamisches Array oder Klasse als Array auslegen
 
Guten Morgen.

Code:
winampDsp->handle = ++winampDSPhandle;
Das entspricht:

Delphi-Quellcode:
// durch den vorangestellten Operator ++ zuerst erhöhen:
Inc(winampDSPhandle);
// dann zuweisen:
winampDsp^.handle := winampDSPhandle;
Denke wieder daran, dass ich mich mit den Bezeichner auf den C++ Code beziehe und du diese Namen in Delphi abwandeln musst.

Grüße

marabu

EWeiss 24. Sep 2006 10:18

Re: Dynamisches Array oder Klasse als Array auslegen
 
Zitat:

Denke wieder daran, dass ich mich mit den Bezeichner auf den C++ Code beziehe und du diese Namen in Delphi abwandeln musst.
Auch einen guten Morgen ...

ja werde ich ;)
Was ich das bisher so sehe ist es fast unmöglich den Quelltext von C++ nach Delphi zu übersetzen
zu viele unterschiede und man weiß nicht wo man ansetzen soll.

Habe mich die halbe Nacht mit dem Problem beschäftigt warum beim initialisieren
von den modulen immer ein Totalcrash auftritt.

Bin dann darauf gekommen einen globalen Pointer als Funktion zu definieren
und diesen mit der aktiven ProcessAdresse zu verbinden.
Die Module laufen nun aber mit einschränkung.

Delphi-Quellcode:
pGetMod                  : function : pointer; stdcall;
pGetMod := GetProcAddress(winampDsp^.hDll, 'winampDSPGetHeader2');
Erst dadurch war es mir möglich die Module richtig einzulesen.
Für euch mag das selbstverständlich sein .. aber bei mir mit nicht so viel wissen
was Delphi angeht war das schon ein fortschritt. :wink:

Kannst vielleicht mal über diese Funktion schauen?
Da stimmt irgendetwas mit den IF abfrageverbund nicht
Fehler!

Zitat:

[Pascal Warning] BassWaDSP.pas(573): W1035 Return value of function 'BASS_WADSP_Load' might be undefined



Delphi-Quellcode:
 // Läd ein Winamp DSP Plugin und übergibt das handle
 // Koordinaten und ein User Callback können übergeben werden
function BASS_WADSP_Load(const dspfile: PChar; x, y, Width, Height: integer;
                         proc: WINAMPWINPROC): HDSP; stdcall;

var
  winampDsp: WINAMPPLUGINPROPDSP;
  cnt: integer;

begin
  winampDsp := AllocMem(sizeof(WINAMPPLUGINPROPDSP));
  FillChar(winampDsp, 0, sizeof(winampDsp));

  Saved8087CW := Default8087CW;
  //FPU - Exceptions deaktivieren
  Set8087CW($133f);

  // Library laden
  // zuerst mit unicode versuchen
  winampDsp^.hDll := LoadLibraryW(PWideChar(dspfile));
  if (not winampDsp^.hDll) <> 0 then
  begin
    // ansonsten Ansi
    winampDsp^.hDll := LoadLibrary(dspfile);
  end;

  // Exceptions zurück auf Defaultwert
  Set8087CW(Saved8087CW);

  if winampDsp^.hDll <> 0 then
  begin
    pGetMod := GetProcAddress(winampDsp^.hDll, 'winampDSPGetHeader2');
    if pGetMod <> nil then
    begin
      // Fake Winamp Window erstellen
      if (Create_Winamp_Window(winampDsp, x, y, Width, Height, proc)) = True then
      begin
        cnt := 0;
        winampDsp^.pModule := pGetMod;
        if winampDsp^.pModule <> nil then
        begin
          // Schleife durchlaufen bis kein Modul mehr gefunden wurde
          repeat
            Inc(cnt);
          until winampDsp^.pModule^.getModule(cnt) = nil;
          // Anzahl der Module speichern
          winampDsp^.NumberOfModules := cnt;
          winampDsp^.module := -1;
          InitializeCriticalSection(winampDsp^.csH);
          // Addiere ein neues Winamp DSP Plugin
          AddDSP(winampDsp);
          // Übergebe das Handle
          Result := winampDsp^.handle
      end else
        // Bei Fehler Winamp Fake Window beenden
        Destroy_Winamp_Window(winampDsp);
    end;
    // Library freigeben
    FreeLibrary(winampDsp^.hDll);
    end else
    // Hierhin, wenn irgend ein fehler autritt.
    FreeMem(winampDsp);
  end else
    Result := 0;

end;
GRüße

marabu 24. Sep 2006 10:28

Re: Dynamisches Array oder Klasse als Array auslegen
 
Um dem Compiler Entwarnung zu geben: Nimm die Zuweisung von 0 an Result aus dem äußeren ELSE-Zweig weg und stelle sie ohne Bedingung vor das IF Statement.

marabu

EWeiss 24. Sep 2006 10:34

Re: Dynamisches Array oder Klasse als Array auslegen
 
Zitat:

Zitat von marabu
Um dem Compiler Entwarnung zu geben: Nimm die Zuweisung von 0 an Result aus dem äußeren ELSE-Zweig weg und stelle sie ohne Bedingung vor das IF Statement.

marabu

Sorry verstehe ich jetzt nicht!

free(winampDsp);
return 0;

müßten ja eigentlich in einen verbund bleiben.
Damit bei einen Fehler Das Mem auch wieder freigegeben wird.

Weiß jetzt nicht welche IF anweisung du meinst. :oops:

grüße

marabu 24. Sep 2006 10:39

Re: Dynamisches Array oder Klasse als Array auslegen
 
Schau mal:

Delphi-Quellcode:
begin
  // ...

  // Exceptions zurück auf Defaultwert
  Set8087CW(Saved8087CW);

  Result := 0; // spätestens hier initialisieren

  if winampDsp^.hDll <> 0 then
  begin
    // ...
    FreeMem(winampDsp);
  end; // else Result := 0; // wird hier nicht mehr gebraucht
end;
Verständlicher so?

marabu

EWeiss 24. Sep 2006 10:45

Re: Dynamisches Array oder Klasse als Array auslegen
 
Zitat:

Zitat von marabu
Schau mal:

Delphi-Quellcode:
begin
  // ...

  // Exceptions zurück auf Defaultwert
  Set8087CW(Saved8087CW);

  Result := 0; // spätestens hier initialisieren

  if winampDsp^.hDll <> 0 then
  begin
    // ...
    FreeMem(winampDsp);
  end; // else Result := 0; // wird hier nicht mehr gebraucht
end;
Verständlicher so?

marabu

Verstanden ja ;)
Aber wo springe ich dann hin wenn das FakeWindow nicht erstellt werden konnte.
Dann muss ich ja auch den Speicher freigeben und das Result := 0; an die Anwendung übergeben.

An die erste Zeile kann ich ja dann nicht springen.



Grüße ..

marabu 24. Sep 2006 10:52

Re: Dynamisches Array oder Klasse als Array auslegen
 
Das von dir ausgemachte Problem existiert nicht. Wenn ich nichts übersehen habe, dann müsstest du bei einem code-walk-through feststellen, dass beim Scheitern von Create_Winamp_Window() die Routine Destroy_Winamp_Window() aufgerufen wird, wie vorher auch schon.

marabu

EWeiss 24. Sep 2006 10:56

Re: Dynamisches Array oder Klasse als Array auslegen
 
Zitat:

Zitat von marabu
Das von dir ausgemachte Problem existiert nicht. Wenn ich nichts übersehen habe, dann müsstest du bei einem code-walk-through feststellen, dass beim Scheitern von Create_Winamp_Window() die Routine Destroy_Winamp_Window() aufgerufen wird, wie vorher auch schon.

marabu

Ja das stimmt ;) Sorry

gruß

EWeiss 25. Sep 2006 10:13

Re: Dynamisches Array oder Klasse als Array auslegen
 
Irgendwie bekomme ich das nicht gebacken.

Delphi-Quellcode:
// Returns the name of a loaded Winamp DSP plugin
function BASS_WADSP_GetName(plugin: HDSP): LPTSTR; stdcall;
Var
  strRet: PChar;
  winampDSP: WINAMPPLUGINPROPDSP;

begin
  strRet := nil;
  winampDsp := GetDSP(plugin);
   if winampDsp <> nil then
   begin
      strRet := winampDsp^.pModule^.description;
   end;
   Result := strRet;
end;
In BASS_WADSP_Load und AddDSP klappt jetzt alles bis in der obigen GetName funktion
wenn ich von dort aus in winampDsp := GetDSP(plugin); springe

Delphi-Quellcode:
function GetDSP(handle: DWORD): WINAMPPLUGINPROPDSP; stdcall;
var
  a: DWORD;
  winampDSP: WINAMPPLUGINPROPDSP;

begin
  if not handle <> 0 then
    Result := nil;

  for a := 0 to winampDSPcounter do
    winampDsp := Winamp_DSP^[a];
  if (winampDSP <> nil) and (winampDSP^.handle = handle) then
  begin
    Result := winampDsp;
  end else

    Result := nil;

end;
werden mir bei der ausgabe Result := winampDsp; komplett andere Werte angegeben
so als wenn die letzen aufrufe nicht mehr existieren würden.


gruß

EWeiss 25. Sep 2006 13:45

Re: Dynamisches Array oder Klasse als Array auslegen
 
Niemand ne Idee ?
Schade...

gruß

marabu 25. Sep 2006 14:08

Re: Dynamisches Array oder Klasse als Array auslegen
 
Hallo Emil,

kann es nicht sein, dass der Rückgabewert von GetDSP ein Zeiger PWinampPluginPropDsp ist? Außerdem bist du eventuell in eine weitere Falle getappt: während in C++ die function mit der Rückgabe eines Wertes verlassen wurde, verbleibt Object Pascal im code block, auch wenn du der Pseudo Variable Result etwas zugewiesen hast.

Grüße vom marabu

EWeiss 25. Sep 2006 17:44

Re: Dynamisches Array oder Klasse als Array auslegen
 
Zitat:

Zitat von marabu
Hallo Emil,

kann es nicht sein, dass der Rückgabewert von GetDSP ein Zeiger PWinampPluginPropDsp ist? Außerdem bist du eventuell in eine weitere Falle getappt: während in C++ die function mit der Rückgabe eines Wertes verlassen wurde, verbleibt Object Pascal im code block, auch wenn du der Pseudo Variable Result etwas zugewiesen hast.

Grüße vom marabu

In BASS_WADSP_Load nach AddDSP wenn das Result übergeben wurde habe
ich noch 100% Werte danach wird ein Handle von 1 übergeben
was auch stimmt (habe es mit der originalen DLL verglichen)
Das Modul mit Version und Description sind auch in Ordnung.

Zum schluß kommt
FreeLibrary(winampDsp^.hDll);

Habe erst gedacht das diese zeile alle werte löscht.
Müßte sie theoretisch auch, habe sie deshalb mal auskommentiert.
Aber gleiche fehler.

Alle Werte gehen unterwegs verloren.

Eine Pseudo Variable kannst eigentlich nicht sein ist ja alles an daten vorhanden
die ich zur übergabe benötige.

Gruß

marabu 25. Sep 2006 17:59

Re: Dynamisches Array oder Klasse als Array auslegen
 
Result ist eine Pseudo-Variable, sie steht für den Funktionsrückgabewert. Du könntest genausogut den Rückgabewert an den Funktionsnamen übergeben, was aber nicht so wartungsfreundlich ist. Die Funktion wird dabei aber nicht beendet, wie z.B. bei der Anweisung return in C. Soweit die Begriffsklärung. Näheres findest du in der Delphi Online-Hilfe. Hier mein Versuch einer Umsetzung - ohne doppelte Negation:

Delphi-Quellcode:
function GetDSP(handle: DWORD): WINAMPPLUGINPROPDSP;
var
  i: DWORD;
begin
  if handle <> 0 then
    for i := 0 to Pred(winampDSPcounter) do
    begin
      Result := Winamp_DSP^[i];
      if Assigned(Result) and (Result^.handle = handle)
        then Exit;
    end;
  Result := nil;
  // GetDSP := nil // gleichwertig
end;
Gruß

marabu

EWeiss 25. Sep 2006 18:11

Re: Dynamisches Array oder Klasse als Array auslegen
 
Zitat:

Zitat von marabu
Result ist eine Pseudo-Variable, sie steht für den Funktionsrückgabewert. Du könntest genausogut den Rückgabewert an den Funktionsnamen übergeben, was aber nicht so wartungsfreundlich ist. Die Funktion wird dabei aber nicht beendet, wie z.B. bei der Anweisung return in C. Soweit die Begriffsklärung. Näheres findest du in der Delphi Online-Hilfe. Hier mein Versuch einer Umsetzung - ohne doppelte Negation:

Delphi-Quellcode:
function GetDSP(handle: DWORD): WINAMPPLUGINPROPDSP;
var
  i: DWORD;
begin
  if handle <> 0 then
    for i := 0 to Pred(winampDSPcounter) do
    begin
      Result := Winamp_DSP^[i];
      if Assigned(Result) and (Result^.handle = handle)
        then Exit;
    end;
  Result := nil;
  // GetDSP := nil // gleichwertig
end;
Gruß

marabu

Also bei dir sieht es schon mal gut aus der zweite Durchlauf der Schleife würde zum erfolg
führen wenn bei der abfrage nach dem Modul nicht ein AV auftreten würde.

Hier sind mal ein paar kleine pics der reihe nach was bei mir abgeht.

Am wichtigsten sind 3 und 4 die Addresse wird noch richtig angezeigt so wie von
AddDSP an BASS_WADSP_Load übergeben
Winamp_DSP zeigt auch noch den richtigen wert.
Aber die Adresse wird wie im nächsten Pic zu sehen von Winampdsp nicht richtig angenommen.

Liebe grüße

marabu 25. Sep 2006 18:29

Re: Dynamisches Array oder Klasse als Array auslegen
 
Die observierte Zeile in Bild-1 - muss es da nicht winamp_DSP^[a] heißen? Prüfe das mal.

Gruß, marabu

EWeiss 25. Sep 2006 18:41

Re: Dynamisches Array oder Klasse als Array auslegen
 
Zitat:

Zitat von marabu
Die observierte Zeile in Bild-1 - muss es da nicht winamp_DSP^[a] heißen? Prüfe das mal.

Gruß, marabu


Delphi-Quellcode:
  TDspPtrArray             = array [0..0] of WINAMPPLUGINPROPDSP;
  DspPtrArray              = ^TDspPtrArray;
  Winamp_DSP               : DspPtrArray = nil;
Ist das gleiche wie im C++ code WinampDSP da wird kein pointer auf die Adresse gesetzt.
Habe es aber mal getestet ergebnis ist das gleiche(AV)

Dein Code der letzte funktioniert 100 pro.
Denke es liegt nun daran das die adresse zum Modul nicht aufgelößt wird
da gibt es ein AV.

Delphi-Quellcode:
// Returns the name of a loaded Winamp DSP plugin
function BASS_WADSP_GetName(plugin: HDSP): LPTSTR; stdcall;
Var
  strRet: PChar;
  winampDSP: WINAMPPLUGINPROPDSP;

begin
  strRet := nil;
  winampDsp := GetDSP(plugin);
   if winampDsp <> nil then
   begin
      strRet := winampDsp^.pModule^.description;
   end;
   Result := strRet;
end;
Wie komme ich auf die Adresse des Moduls? ohne AV
IN Load hat es so funktioniert

Delphi-Quellcode:
    pGetMod                  : function : pointer; stdcall;
    pGetMod := GetProcAddress(winampDsp^.hDll, 'winampDSPGetHeader2');
    if pGetMod <> nil then
gruß

marabu 25. Sep 2006 19:01

Re: Dynamisches Array oder Klasse als Array auslegen
 
Wenn der Zugriff auf winampDsp^.hDll funktioniert, dann scheint der Zeiger winampDsp gesund zu sein. Was sagt denn der Debugger bei winampDsp^.pModule - ist der Zeiger eventuell nil? Hast du die Struktur irgendwo korrekt initialisiert?

Gruß, marabu

EWeiss 25. Sep 2006 19:07

Re: Dynamisches Array oder Klasse als Array auslegen
 
Zitat:

Zitat von marabu
Wenn der Zugriff auf winampDsp^.hDll funktioniert, dann scheint der Zeiger winampDsp gesund zu sein. Was sagt denn der Debugger bei winampDsp^.pModule - ist der Zeiger eventuell nil? Hast du die Struktur irgendwo korrekt initialisiert?

Gruß, marabu

ja der Zeiger ist NIL
Deshalb meine Anmerkung wie ich die 'winampDsp^.pModule' Adresse auflösen kann.
Es siehst so aus das zum Modul der POinter fehlt.

PS: In VB braucht man diese ganze Pointer sache nur in seltenen fällen
Sorry wenn ich manchmal etwas dumm frage.
Werde es aber auf kurz oder lang begreifen.

Danke .. grüße

EWeiss 25. Sep 2006 19:16

Re: Dynamisches Array oder Klasse als Array auslegen
 
Zitat:

Zitat von EWeiss
Zitat:

Zitat von marabu
Wenn der Zugriff auf winampDsp^.hDll funktioniert, dann scheint der Zeiger winampDsp gesund zu sein. Was sagt denn der Debugger bei winampDsp^.pModule - ist der Zeiger eventuell nil? Hast du die Struktur irgendwo korrekt initialisiert?

Gruß, marabu

ja der Zeiger ist NIL
Deshalb meine Anmerkung wie ich die 'winampDsp^.pModule' Adresse auflösen kann.
Es siehst so aus das zum Modul der POinter fehlt.

PS: In VB braucht man diese ganze Pointer sache nur in seltenen fällen
Sorry wenn ich manchmal etwas dumm frage.
Werde es aber auf kurz oder lang begreifen.

Danke .. grüße

Ahhhhhh ... Erfolg
Dein Hinweis auf winampDsp^.hDll hat mich den code nochmal überprüfen lassen.
Es lag ganz einfach daran das unter Load BASS_WADSP_Load

Delphi-Quellcode:
      end else
        // Bei Fehler Winamp Fake Window beenden
        Destroy_Winamp_Window(winampDsp);
    end;
    // Library freigeben
     FreeLibrary(winampDsp^.hDll);
freigegeben wurde. Deshalb konnte 'winampDsp^.pModule' nicht mehr initialisiert werden weil NIL.
Da nach BASS_WADSP_GetName keine weitere Funktion zum einladen mehr benötigt wird
sollte ich diese Zeile 'FreeLibrary(winampDsp^.hDll)' wohl unter 'strRet := winampDsp^.pModule^.description;' setzen.

gruß

PS: Letzte feststellung war quatch
Zitat:

sollte ich diese Zeile 'FreeLibrary(winampDsp^.hDll)' wohl unter 'strRet := winampDsp^.pModule^.description;' setzen.
Habe einfach aus end; end else gemacht
So kann 'if pGetMod <> nil then' pGetMod die Library leeren wenn = NIL.

EWeiss 25. Sep 2006 20:19

Re: Dynamisches Array oder Klasse als Array auslegen
 
Bis GetName funktioniert nun alles.
Mein neues problem ist nicht ganz so aufwendig denke ich!

Delphi-Quellcode:
procedure Destroy_Winamp_Window(winampDsp: WINAMPPLUGINPROPDSP); stdcall;
begin

       EnterCriticalSection(winampDsp^.csH);

      if winampDsp^.DSP_Window_Emu <> 0 then
         DestroyWindow(winampDsp^.DSP_Window_Emu);
      if winampDsp^.DSP_Atom_Emu <> 0 then
         UnRegisterClass(PChar(WORD(winampDsp^.DSP_Atom_Emu)), Inst);

      winampDsp^.DSP_Atom_Emu := 0;
      winampDsp^.DSP_Window_Emu := 0;

      LeaveCriticalSection(winampDsp^.csH);

end;
Im Original wird diese Zeile
Delphi-Quellcode:
EnterCriticalSection(winampDsp^.csH);
so dargestellt.

Code:
EnterCriticalSection(&winampDsp->csH);
Wäre übersetzt
Delphi-Quellcode:
EnterCriticalSection(@winampDsp^.csH);
So wie es oben ist gibt es einen AV nehme ich die übersetzte zeile
bekomme ich die Meldung

Zitat:

[Pascal Error] BassWaDSP.pas(330): E2033 Types of actual and formal var parameters must be identical
Der Operator '@' müßte ja die adresse der Variablen zurückliefern so wie ich das verstanden habe
Ausgelegt ist sie in der Classe.

Delphi-Quellcode:
csH                      : RTL_CRITICAL_SECTION;
Was ist hier verkehrt das diese Meldung auftritt ?

Gruß

EWeiss 26. Sep 2006 06:36

Re: Dynamisches Array oder Klasse als Array auslegen
 
Guten Morgen @all

Delphi-Quellcode:
  //WinampDSPInfo Klasse
  WINAMPPLUGINPROPDSP = ^WINAMPPLUGINPROP_TAG_DSP;
  WINAMPPLUGINPROP_TAG_DSP  = record
     csH                      : RTL_CRITICAL_SECTION;         // CRITICAL_SECTION
     handle                   : DWORD;                         // DSP handle
     NumberOfModules          : UINT;                          // number of modules in the dsp
     hDll                     : HWND;                          // the dll instance
     pModule                  : PWinampDSPHeader;              // module header
     pDSP                     : PWinampDSPModule;              // current selected dsp module
     hchannel                 : DWORD;                         // channel associated to dsp
     module                   : Integer;                       // curent selected dsp module
     hdsp                     : HDSP;                          // optional dsp handle
     DSP_Window_Emu           : HWND;                          // related fake window handle
     DSP_Atom_Emu             : ATOM;                          // related fake window atom
     songTitle                : array[0..MAX_PATH-1] of char; // the playing song title
     fileName                 : array[0..MAX_PATH-1] of char; // the playing file name
     info                     : BASS_CHANNELINFO;              // channel info
  end;
Wie kann ich erreichen das bei der übergabe des '@' Operators an

EnterCriticalSection(@winampDsp^.csH);
kein AV auftritt ?

Also ohne Operator hängt sich die Anwendung auf oder es gibt ein AV.
EnterCriticalSection(winampDsp^.csH);
Mit Operator kommt diese Meldung!
Zitat:

[Pascal Error] BassWaDSP.pas(330): E2033 Types of actual and formal var parameters must be identical
Weiß jetzt nicht wie ich den Operator in der Classe einfügen muss damit die Meldung nicht mehr kommt.

Gruß

marabu 26. Sep 2006 07:02

Re: Dynamisches Array oder Klasse als Array auslegen
 
Guten Morgen Emil.

Bei csh: DWORD handelt es sich wahrscheinlich um einen Pointer auf die CRITICAL_SECTION Struktur. So könnte es funktionieren:

Delphi-Quellcode:
 EnterCriticalSection(PRTLCriticalSection(winampDsp^.csh)^);
Delphi kapselt dieses kernel object übrigens in der Komponente TCriticalSection.

Grüße vom marabu

EWeiss 26. Sep 2006 07:11

Re: Dynamisches Array oder Klasse als Array auslegen
 
Zitat:

Delphi kapselt dieses kernel object übrigens in der Komponente TCriticalSection.
Wäre dann nicht eigentlich die richtige zuweisung von csh
Delphi-Quellcode:
csH                      : ^TCriticalSection;         // CRITICAL_SECTION
oder verwechsele ich das jetzt?

Danke wiedermal für deine Hilfe.
Grüße aus Kölle am ring.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:54 Uhr.
Seite 1 von 2  1 2      

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