AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Übergabe von Listen an DLL ohne Kopie zu erstellen.
Thema durchsuchen
Ansicht
Themen-Optionen

Übergabe von Listen an DLL ohne Kopie zu erstellen.

Ein Thema von Ookami · begonnen am 2. Jan 2012 · letzter Beitrag vom 2. Jan 2012
 
snook

Registriert seit: 25. Jun 2010
94 Beiträge
 
Delphi 2005 Professional
 
#2

AW: Übergabe von Listen an DLL ohne Kopie zu erstellen.

  Alt 2. Jan 2012, 15:41
Also ich hab das ganze über ne Klasse gelöst, die den Zugriff auf die Liste über interfaces kapselt. Um möglichst kompatibel mit verschiedenen Datentypen zu sein hab ich mir zuerst nen record definiert:

Delphi-Quellcode:
  PDataModuleItem = ^TDataModuleItem;
  TDataModuleItem = packed record
    Key : Pointer;
    Value : Pointer;
    datatype: word;
    Size : integer;
  end;
Dann baust du dir nen interface, das du an die DLL übergibst und den Zugriff auf die Listenelemente bereitstellt:

Delphi-Quellcode:
  IDataModule = interface(IEnumerator)
  ['{57AF81B3-B7A8-4B33-8174-C2DBA70DAC97}']
    function GetLinked: boolean; stdcall;
    procedure GetLink(out Link); stdcall;
    procedure SetLink(const ALink: IInterface); stdcall;
    procedure RemoveLink; stdcall;
    function GetValueCount: integer; stdcall;
    function GetValue(index: integer): Pointer; stdcall; // liefert PDataModuleItem zurück
    procedure SetValue(index: integer; Value: Pointer); stdcall;
    procedure DeleteValue(index: integer); overload; stdcall;
    procedure DeleteValue(Key: PChar); overload; stdcall;
    function HasValue(Key: PChar): boolean; stdcall;
    procedure SetCharValue(AKey: PChar; AValue: PChar); stdcall;
    function GetCharValue(AKey: PChar): PChar; stdcall;
    procedure SetFloatValue(AKey: PChar; AValue: real); stdcall;
    function GetFloatValue(AKey: PChar): real; stdcall;
    procedure SetIntValue(AKey: PChar; AValue: Int64); stdcall;
    function GetIntValue(AKey: PChar): Int64; stdcall;
    procedure SetBoolValue(AKey: PChar; AValue: boolean); stdcall;
    function GetBoolValue(AKey: PChar): boolean; stdcall;

    property ValueCount: integer read GetValueCount;
    property Linked: boolean read GetLinked;
  end;
Das interface kann gleich noch nen interface besitzen, dass als Link fungiert und dem Besitzer mitteilt ob sich was geändert hat

Jetzt musst du dir nur noch ne Klasse definieren, die dieses Interface implementiert und schon kannst du das in die DLL rüberschicken bei Bedarf. Als Auszug könnte das so aussehen

Delphi-Quellcode:

function TCustomDataModule.GetCharValue(AKey: PChar): PChar;
var index: integer;
begin
  result := nil;
  index := IndexOf(AKey);
  with FList.LockList do
    try
      if (index > -1) and
         (PDataModuleItem(Items[index])^.datatype = STR_DATA) then
          result := PChar(PDataModuleItem(Items[index])^.Value);
    finally
      FList.UnlockList;
    end;
end;

procedure TCustomDataModule.SetCharValue(AKey: PChar; AValue: PChar);
var Buffer: PDataModuleItem;
begin
  Buffer := nil;
// if IndexOf(AKey) > -1 then
    try
      Buffer := NewDataModuleItem(STR_DATA);
      Buffer^.Key := CopyPChar(AKey);
      Buffer^.Value:= CopyPChar(AValue);
      SetValue(IndexOf(AKey),Buffer);
    finally
      DisposeDataModuleItem(Buffer);
    end;
end;

procedure TCustomDataModule.SetValue(index: integer; Value: Pointer);
var Buffer: PDataModuleItem;
begin
  Buffer := nil;
  if (index > -1) and (index < ValueCount) then
    with FList.LockList do
      try
        Buffer := Items[index];
      finally
        FList.UnlockList;
      end;
  if Assigned(Buffer) then
  begin
    LinkNotification(Buffer^.Key, Buffer^.datatype, lnsChanging);
    DisposeDataModuleItem(Buffer);
  end;
  Buffer := CopyDataModuleItem(PDataModuleItem(Value));

  if Assigned(Buffer) then
    with FList.LockList do
      try
        if (index > -1) and (index < Count) then
          Items[index] := Buffer
        else
          Add(Buffer);
        LinkNotification(Buffer^.Key, Buffer^.datatype, lnsChanged);
      finally
        FList.UnlockList;
      end;
end;
FList is ne ThreadList, damit bist du auch noch Threadsafe, LinkNotification ist ne Methode des Datenmoduls, die bei Bedarf dem Link mitteilt dass sich was geändert hat

Ach und ebenso gesundes neues

Edit\\ CopyDataModuleItem kopiert das record, wobei du dann je nach pItem^.datatype die Werte sinnvoll kopieren solltest

Geändert von snook ( 2. Jan 2012 um 15:46 Uhr)
  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 06:03 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