Delphi-PRAXiS
Seite 1 von 6  1 23     Letzte »    

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ß ..


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:06 Uhr.
Seite 1 von 6  1 23     Letzte »    

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