[Erledigt] Array Pointer Verwirrung

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
compmgmt
Beiträge: 351
Registriert: Mi 25. Nov 2015, 17:06
OS, Lazarus, FPC: Win 10 Pro | Lazarus 1.8.2 | FPC 3.0.4
CPU-Target: i386 + x86_64
Wohnort: in der Nähe von Stuttgart
Kontaktdaten:

[Erledigt] Array Pointer Verwirrung

Beitrag von compmgmt »

Guten Abend allerseits,

ich bin grade etwas verwundert oder sehe den Wald vor lauter Bäumen nicht. Jedenfalls möchte ich den Pointer eines statischen Arrays als Pointer über eine DLL übergeben. Folgendes habe ich gemacht:

Code: Alles auswählen

type
  TSHA256 = array[0..31] of Byte;
  PSHA256 = ^TSHA256;
  ...
  function SHA256(s: String): TSHA256; // Hash generieren, funktioniert auch korrekt
  function SHA256ToString(Hash: TSHA256): String;

Und hier das Aufrufen (testweise ohne DLL):

Code: Alles auswählen

var
  Hash: TSHA256;
  p: PSHA256;
begin
  Hash := SHA256('Irgendwas');
  ShowMessage(SHA256ToString(Hash)); // Der korrekte Hash wird ausgegeben
  p := @Hash;
  ShowMessage(SHA256ToString(p^)); // Hier kommt Quark raus
end;

Was übersehe ich?
Zuletzt geändert von compmgmt am Fr 25. Jan 2019, 21:14, insgesamt 1-mal geändert.

Code: Alles auswählen

InitiateSystemShutdownExA(nil, nil, 0, true, false, $0005000F);
Have fun with this snippet ;)

Warf
Beiträge: 1909
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Array Pointer Verwirrung

Beitrag von Warf »

Keine ahnung warum das bei dir nicht geht, bei mir funktioniert das so:

Code: Alles auswählen

procedure Test;
type TTestArr = array[0..5] of Byte;
  PTestArr = ^TTestArr;
 
  function ArrToString(const arr: TTestArr): String;
  var
    i: Integer;
  begin
    Result := '';
    for i:=Low(arr) to High(arr) do
      Result += arr[i].ToString + ' ';
    Result := Result.Remove(Result.Length-1);
  end;
 
var t: TTestArr;
  p: PTestArr;
  i: Integer;
begin
  for i:=0 to 5 do t[i] := i;
  ShowMessage(ArrToString(t));
  for i:=0 to 5 do t[i] := i+1;
  p := @t;
  ShowMessage(ArrToString(p^));
end;


Aber:

Code: Alles auswählen

function SHA256ToString(const Hash: TSHA256): String;

Benutz const im Parameter, sonst wird beim funktionsaufruf das gesammte Objekt (alle 32 Bytes) kopiert. Via const wird nur eine referenz verwendet.

compmgmt
Beiträge: 351
Registriert: Mi 25. Nov 2015, 17:06
OS, Lazarus, FPC: Win 10 Pro | Lazarus 1.8.2 | FPC 3.0.4
CPU-Target: i386 + x86_64
Wohnort: in der Nähe von Stuttgart
Kontaktdaten:

Re: Array Pointer Verwirrung

Beitrag von compmgmt »

Achso, ich dachte immer wenn man nichts vor ein Argument schreibt ist es automatisch const. Man lernt nie aus. Da werde ich wohl bei einigen meiner Funktionen etwas ändern.

Code: Alles auswählen

InitiateSystemShutdownExA(nil, nil, 0, true, false, $0005000F);
Have fun with this snippet ;)

compmgmt
Beiträge: 351
Registriert: Mi 25. Nov 2015, 17:06
OS, Lazarus, FPC: Win 10 Pro | Lazarus 1.8.2 | FPC 3.0.4
CPU-Target: i386 + x86_64
Wohnort: in der Nähe von Stuttgart
Kontaktdaten:

Re: Array Pointer Verwirrung

Beitrag von compmgmt »

Gut, ich bin jetzt einen Schritt weiter. Der oben aufgeführte Code funktioniert wunderbar. Um zu verstehen warum es nicht bei mir klappt erkläre ich was die DLL genau macht. In einer anderen Funktion erwartet die DLL einen PSHA256 als Argument. Damit das Hostprogramm keine Implementierung zur Hashgenerierung benötigt, exportiert meine DLL eine Funktion "GenerateSHA256". Diese ist der Übeltäter und gibt den Datenquark zurück. Innerhalb der DLL wird der Hash korrekt generiert, aber scheinbar nicht korrekt zurückgegeben.

Dazu habe ich ein Testprojekt erstellt:

Hier die DLL:

Code: Alles auswählen

function GenerateFakeHash: PSHA256;
var
   Hash: TSHA256;
begin
  Hash := SHA256('Irgendwas');
  Result := @Hash;
  MessageBoxA(0, LPCSTR('DLL GenerateFakeHash: ' + SHA256ToString(Result^)), 'Hash', MB_OK); // An dieser Stelle ist der eben generierte Hash korrekt
end;

Und hier die EXE:

Code: Alles auswählen

function GenerateFakeHash: PSHA256; stdcall; external 'TestDLL';
...
var
  p: PSHA256;
begin
  ...
  p := GenerateFakeHash;
  WriteLn(SHA256ToString(p^)); // Hier kommt etwas falsches raus
  ...
end.

Im Anhang ist das Beispielprojekt.

P.S.: Da vermutlich nicht jeder DCPCrypt installiert hat habe ich die Hashgenerierung modifiziert und sie gibt einen FakeHash aus, welcher immer der gleiche ist, egal was man als String angibt.
Dateianhänge
HashTest.zip
Hashgenerierung via DLL Testprojekt
(205.96 KiB) 89-mal heruntergeladen

Code: Alles auswählen

InitiateSystemShutdownExA(nil, nil, 0, true, false, $0005000F);
Have fun with this snippet ;)

compmgmt
Beiträge: 351
Registriert: Mi 25. Nov 2015, 17:06
OS, Lazarus, FPC: Win 10 Pro | Lazarus 1.8.2 | FPC 3.0.4
CPU-Target: i386 + x86_64
Wohnort: in der Nähe von Stuttgart
Kontaktdaten:

Re: Array Pointer Verwirrung

Beitrag von compmgmt »

Ich hatte gerade einen Geistesblitz. Natürlich kann es nicht funktionieren, da "Hash" ja nach dem Aufruf wieder freigegeben wird. Den Wald vor lauter Bäumen mal wieder nicht gesehen.

Code: Alles auswählen

InitiateSystemShutdownExA(nil, nil, 0, true, false, $0005000F);
Have fun with this snippet ;)

Warf
Beiträge: 1909
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: [Erledigt] Array Pointer Verwirrung

Beitrag von Warf »

compmgmt hat geschrieben:Achso, ich dachte immer wenn man nichts vor ein Argument schreibt ist es automatisch const. Man lernt nie aus. Da werde ich wohl bei einigen meiner Funktionen etwas ändern.


Nein, wenn man nichts davor schreibt hat man so zu sagen eine Arbeitskopie, die man in der Prozedur beliebig ändern kann, z.B. für den 2er Logarithmus zu berechnen:

Code: Alles auswählen

function Log2(i: Integer): Integer;
begin
  Result:=0;
  while i>1 do
  begin
    Inc(Result);
    i := i shr 1;
  end;
end;

compmgmt hat geschrieben:Ich hatte gerade einen Geistesblitz. Natürlich kann es nicht funktionieren, da "Hash" ja nach dem Aufruf wieder freigegeben wird. Den Wald vor lauter Bäumen mal wieder nicht gesehen.

Sowas passiert immer mal

Antworten