AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Dynamisches Array von DLL übergeben

Ein Thema von TheMiller · begonnen am 4. Dez 2006 · letzter Beitrag vom 8. Dez 2006
 
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.372 Beiträge
 
Delphi 12 Athens
 
#25

Re: Dynamisches Array von DLL übergeben

  Alt 6. Dez 2006, 17:55
Zitat von Wormid:
Delphi-Quellcode:
library Project1;

type
  TTestArray = array of ShortString; // <--- ShortString !!!
  PTestArray = ^TTestArray;

function GetTestArray: PTestArray; stdcall;
var
  a: TTestArray;
begin
  SetLength(a, 3);
  a[0] := 'Hallo';
  a[1] := 'Welt';
  a[2] := '!';
  Result := PTestArray(a);
end;

exports
  GetTestArray;

begin
end.
Zitat von ste_ett:
Dadurch, dass du einen Pointerauf den Array als Rpckgabewert übergibst, wird jeglicher Speicher, der für den Array reserviert wurde wieder als beschreibbar markiert. Nur die vier Byte für den Pointer sind fest. Theoretisch könnte in der Millisekunde nach zurückgeben des Pointers eine andere Anwendung den Speicher, wo die drei Array-Elemente liegen, wieder nutzen.
Stimmt, was das mit dem Freigeben angeht ... man könnte Delphi ja auch daran hindern das Array automatisch freizugeben...
Delphi-Quellcode:
library Project1;

type
  TTestArray = array of ShortString; // <--- ShortString !!!
  PTestArray = ^TTestArray;

function GetTestArray: PTestArray; stdcall;
var
  a: TTestArray;
begin
  SetLength(a, 3);
  a[0] := 'Hallo';
  a[1] := 'Welt';
  a[2] := '!';
  Result := PTestArray(a);
  Pointer(a) := nil; // Array-Variable als Leer definieren
end;

procedure FreeTestArray(a: PTestArray); stdcall;
begin
  SetLength(TTestArray(a), 0);
end;

exports
  GetTestArray,
  FreeTestArray;

begin
end.

Theoretisch ist es aber auch möglich den Speicher(inhalt) komplett an den anderen MemoryManager zu übergeben (außer für Objekte und dergleichen).

Für den Fall des StringArrays gäbe es wohl 2 Hauptmöglichkeiten, entweder man kümmert sich selber um um die Verwaltung des Speichers (reservieren, freigeben, kopieren), oder man nutzt die String- und Arrayfunktionen für's kopieren.

Müßtest aber mal etwas mehr über deine Funktion sagen.
- entwerder die gesammte funktion zeigen
- oder zumindestens deren definition und ob die übergebenen parameter intern verändert werden.




So als Beispiel, wie es eventuell gehen könnte:
Delphi-Quellcode:
Type TExtGetMem = Function(i: Integer): Pointer;

Var ExtGetMem: TExtGetMem;

Procedure SetExtGetMem(G: TExtGetMem);
  Begin
    ExtGetMem := G;
  End;

Function Explode(S, Sep: String): TStringArray;
  Var Temp: PStringArray;
    P: PChar;
    i: Integer;

  Begin
    ...

    // Speicher übergeben ...
    If Result = nil Then Exit;
    Temp := PChar(GetMemory(Length(Result) * 4) + 8) + 8;
    PInteger(Integer(Temp) - 8)^ := 1; // Array.RefCount
    PInteger(Integer(Temp) - 4)^ := Length(Result); // Array.ElementCount
    P := Temp;
    For i := 0 to High(Result) do Begin
      If Result[i] <> 'Then Begin
        PPointer(P)^ := PChar(GetMemory(Length(Result) * 4) + 9) + 8; // Array.Data[i]
        Move((P - 8)^, PChar(Result[i]) - 8, Length(Result[i] + 9);
      End Else PPointer(P)^ := nil;
      Inc(P, 4);
    End;
    Result := nil; // Array leeren
    Pointer(Result) := P; // ArrayDaten des anderen MM zuweisen
  End;

Export
  SetExtGetMem,
  Explode;
Ich hoff i hab's soweit richtig ... war jetzt nur aus'm Kopf und ohne Delphi, also nicht getestet.
Sieht zwar schwerer aus, als es ist, aber im Grunde mußt du nur jeden einzelnen Speicherblock in den anderen MemoryManager kopieren und die Pointer entsprechend anpassen.

Bist du dir also sicher, daß du keinen SharedMM verwenden willst?

ach ja, aufgerufen würde es dann so:
Delphi-Quellcode:
SetExtGetMem(@GetMemory);
...
myStringArray := Explode(S, Sep);
Dat war also die Methode mit dem selber drum kümmern, wobei hier alles in der Methode drin ist, für's Andere geb ich vielleich etwas später noch ä kurzes Beispiel.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:19 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