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/)
-   -   Delphi Vom Record gehen teile verloren (https://www.delphipraxis.net/208321-vom-record-gehen-teile-verloren.html)

venice2 14. Jul 2021 13:27


Vom Record gehen teile verloren
 
Ich habe nen Record und schicke diesen zu einer 32Bit EXE.
Verändere dabei aber nur bestimmte bereiche.
Nicht lachen.. :lol: aber wenn ein Eintrag überschritten wird nimmt die Exe einfach nichts mehr an.

Warum?

Beispiel:
Der record in beiden Exe gleich 64 und 32Bit
Delphi-Quellcode:
  PSOP64 = ^TSOP64;
  TSOP64 = record
    PluginFile: array[0..MAX_PATH - 1] of AnsiChar;
    ConfigFile: array[0..MAX_PATH - 1] of AnsiChar;
    UseSlowFade: BOOL;
    ViewportWidth: Integer;
    ViewportHeight: Integer;
    SlowFadeVal: Integer;
    ParentHandle: HWND;
    FFTAmpVal: Integer; // Dieser Eintrag funktioniert einfach nicht
    FFT: array [0 .. 511] of single;
    Wave: array [0 .. 1023] of smallint;
    Position: DWORD;
  end;
Wird so abgeschickt.

Delphi-Quellcode:
procedure SOP_FFTAmpVal;
begin
  if (gp.hSOPlugin <> 0) then
  begin
    gSOP.FFTAmpVal := gBin.FFTAmpVal;
    gCDS.dwData := dwData_FFTAmpVal;
    gCDS.cbData := SizeOf(gSOP);
    gCDS.lpData := @gSOP;
    SendMessage(gp.hSOPlugin, WM_COPYDATA, WPARAM(gP.MainHandle), LPARAM(@gCDS));
  end;
end;
gBin.FFTAmpVal; (gBin ist ein record mit diversen globalen variablen)
Wenn ich nun meinen Slider bewege wird die Value geändert und an SOP_FFTAmpVal übergeben.

In der 32Bit Exe wird sie so angenommen.
Delphi-Quellcode:
    WM_COPYDATA:
      begin
        pCDS := Pointer(lP);
        case pCDS.dwData of
          5:
            begin
              pSOP := Pointer(pCDS.lpData);
              FFTSAmplification := (11 - Max(1, Min(4, pSOP.FFTAmpVal))) / 10;
            end;
        end;
      end;
pSOP.FFTAmpVal bleibt immer 0.
Verschiebe ich den Eintrag aber an einer höheren Stelle innerhalb des Record (TSOP64) dann funktioniert es.
Was für seltsame Dinge gehen da wieder vor sich.

Die Übergabe der Arrays für die Visualisierung haben kein Problem daher verstehe ich das nicht
obwohl diese unter dem Eintrag vom FFTAmpVal stehen.

Übergeben!
Delphi-Quellcode:
      if (gP.hSOPlugin <> 0) then
      begin
        if (IsMenuChecked(IDC_PLUGIN, hCtrl)) then
        begin
          FFFTdata := GetFFTData;
          CopyMemory(@gSOP.FFT[0], @FFFTdata, 512);
          gSOP.Position := StreamPos;

          FWaveData32 := GetWaveData;
          CopyMemory(@gSOP.Wave[0], @FWaveData32, 1024);
          gCDS.dwData := dwData_OpenGL;
          gCDS.cbData := SizeOf(gSOP);
          gCDS.lpData := @gSOP;
          SendMessage(gP.hSOPlugin, WM_COPYDATA, WPARAM(gP.MainHandle), LPARAM(@gCDS));
        end;
      end;
Und Angenommen\Ausgewertet innerhalb der 32Bit Exe
Delphi-Quellcode:
    WM_COPYDATA:
      begin
        pCDS := Pointer(lP);
        case pCDS.dwData of
          0:
            begin
              pSOP := Pointer(pCDS.lpData);
              Position := pSOP.Position;
              RenderOpenGL(VisHandle, @pSOP.Wave, @pSOP.FFT, Position);
            end;
        end;
      end;
Mir fällt nichts mehr ein was das auslösen könnte.

64Bit Anwendung (verwendet die Bass.dll 64Bit) zur 32Bit Anwendung die dann 32Bit.dll's Sonique Plugins visualisiert.
Ich habe immer davon geredet das man 32Bit Dll's sehr wohl mit einer 64Bit Anwendung verwenden kann.
Wollte das mal hier Demonstrieren :wink: es scheint aber doch kleine Problem zu geben.

Vielleicht den 64Bit Record auf 32Bit trimmen?
Wenn dann nur wie?

PS:
Ich bekomme es auch nicht gebacken das ich beide Exe Dateien miteinander in der IDE Debuggen kann.

TiGü 14. Jul 2021 14:08

AW: Vom Record gehen teile verloren
 
Delphi-Quellcode:
// Bitte kompiliere mich in 32-Bit und in 64-Bit und führe mich aus.


program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  Winapi.Windows;

begin
  try
    Writeln('Size of a HWND: ', SizeOf(HWND), ' bytes!');
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.
Das Problem wird sein, das ParentHandle: HWND ein Handle auf ein Fenster ist und damit eine Art Pointer, dessen Größe sich je nach Bittigkeit von vier auf acht Bytes ändert.
Wenn du Einfluß hast auf das Record, versuche ParentHandle: HWND ans Ende zu setzen.

venice2 14. Jul 2021 14:20

AW: Vom Record gehen teile verloren
 
Zitat:

Zitat von TiGü (Beitrag 1492278)
Delphi-Quellcode:
// Bitte kompiliere mich in 32-Bit und in 64-Bit und führe mich aus.


program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  Winapi.Windows;

begin
  try
    Writeln('Size of a HWND: ', SizeOf(HWND), ' bytes!');
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.
Das Problem wird sein, das ParentHandle: HWND ein Handle auf ein Fenster ist und damit eine Art Pointer, dessen Größe sich je nach Bittigkeit von vier auf acht Bytes ändert.
Wenn du Einfluß hast auf das Record, versuche ParentHandle: HWND ans Ende zu setzen.

Ja habe ich wurde ja von mir Programmiert ;)

Super funktioniert! :thumb: Wäre ich nie drauf gekommen.
Muß mal testen ob es funktioniert wenn ich anstelle HWND Long_Ptr verwende als Type. btw. LongInt
Oder ist dass das gleiche Problem?
Danke!

TiGü 14. Jul 2021 14:43

AW: Vom Record gehen teile verloren
 
Zum Drüber nachdenken:
Was passiert mit dem HWND $112233445566 unter 64-Bit, wenn du es in eine Variable vom Typ LongInt steckst?

Delphi-Quellcode:
program Project6;

{$APPTYPE CONSOLE}
{$R *.res}

uses
    System.SysUtils,
    Winapi.Windows,
    Winapi.Messages,
    System.Classes;

type
    TDummy = class
        procedure WndProc(var Message: TMessage);
    end;

var
    LDummy: TDummy;
    LHandle: HWND;
    LLong_Ptr: LONG_PTR;
    LLongInt: LongInt;

{ TDummy }

procedure TDummy.WndProc(var Message: TMessage);
begin

end;

begin
    try
        Writeln('Size of a HWND: ', SizeOf(HWND), ' bytes!', ' Min: ', Low(HWND), ' High: ', High(HWND));
        Writeln('Size of a LONG_PTR: ', SizeOf(LONG_PTR), ' bytes!', ' Min: ', Low(LONG_PTR), ' High: ', High(LONG_PTR));
        Writeln('Size of a LongInt: ', SizeOf(LongInt), ' bytes!', ' Min: ', Low(LongInt), ' High: ', High(LongInt));

        LDummy := TDummy.Create;
        try
            LHandle := AllocateHWnd(LDummy.WndProc);
            Writeln('HWND: ', UINT_PTR(LHandle).ToHexString);
            LLong_Ptr := LHandle;
            Writeln('LONG_PTR: ', LLong_Ptr.ToHexString);
            LLongInt := LHandle;
            Writeln('LongInt: ', LLongInt.ToHexString);
        finally
            DeallocateHWnd(LHandle);
            LDummy.Free;
        end;
    except
        on E: Exception do
            Writeln(E.ClassName, ': ', E.Message);
    end;
    Readln;

end.

venice2 14. Jul 2021 14:48

AW: Vom Record gehen teile verloren
 
OK Danke geht wohl nicht.
Gutes Beispiel kann ich von lernen um unterschiedliche Typen von Bittigkeit gegen zu prüfen.

Sinspin 14. Jul 2021 15:17

AW: Vom Record gehen teile verloren
 
Dein Record sollte als
Delphi-Quellcode:
packed record
deklariert sein, sonst hat der eventuell in den beiden Programmen eine unterschiedliche Größe.
Oder Du stells für bei Programme die Wordausrichtung manuell ein.
Du übergibst den Record als Variable oder als Zeiger?
Generell, Zeiger in 64Bit Programmen sind nicht vom Typ Cardinal, das musst du bei der Adressübergabe auch beachten!

venice2 14. Jul 2021 15:25

AW: Vom Record gehen teile verloren
 
Zitat:

Dein Record sollte als packed record deklariert sein
Habe ich dran gedacht ;)

Es macht aber keinen Unterschied was mein Problem anging erst die Lösung von @TiGü hat den gewünschten Erfolg gebracht.
Aber wenn ich dadurch eine höhere Sicherheit habe kann ich es noch ändern. Sehe im Moment nur den Vorteil noch nicht.

Uwe Raabe 14. Jul 2021 15:52

AW: Vom Record gehen teile verloren
 
Du könntest den Record in etwa so deklarieren:
Delphi-Quellcode:
  TSOP64 = record
    PluginFile: array[0..MAX_PATH - 1] of AnsiChar;
    ConfigFile: array[0..MAX_PATH - 1] of AnsiChar;
    UseSlowFade: BOOL;
    ViewportWidth: Integer;
    ViewportHeight: Integer;
    SlowFadeVal: Integer;
    ParentHandle: HWND;
{$IFDEF WIN32}
    filler: HWND; { weil 1 HWND-64 = 2 HWND-32 }
{$ENDIF}
    FFTAmpVal: Integer; // Dieser Eintrag funktioniert einfach nicht
    FFT: array [0 .. 511] of single;
    Wave: array [0 .. 1023] of smallint;
    Position: DWORD;
  end;

venice2 14. Jul 2021 15:57

AW: Vom Record gehen teile verloren
 
Danke Uwe wäre eine alternative.

Aber @TiGü sein Vorschlag funktioniert so wie er soll.
Man muß halt nur Aufpassen.

hoika 14. Jul 2021 18:27

AW: Vom Record gehen teile verloren
 
Hallo,
das Alignment wurde schon genannt.
Und das SizeOf des Records sollte unter beiden Bits gleich sein.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:36 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