![]() |
Datenaustausch zw. DLL und Applikation
Abstrakte Frage:
Was ist der beste Weg um zw. einer D3 App und einer D7 dll kompatibel Daten (Liste von Records) zu übertragen? Konkretes Problem: Eine Anwendung die mit Delphi 3 geschrieben ist braucht spezielle Daten die per Web-Service abrufbar sind. Da Web-Services mit Delphi3 nicht "nativ" möglich sind (gibs dafür überhaupt was!? egal) will ich mit D7 eine dll schreiben die die Daten des Web-Services abfragt. Ich möchte eine Struktur kompatibel zw. der D7 DLL und der D3 exe übertragen. Es handelt sich um eine simple Liste von Records die ich auf D3 Seite instanziiere und per var Parameter and die dll weitergebe die sie mir dann befüllt. Die Listen-Klasse hab ich selbst geschrieben (ne einfache verkettete Liste) da TList und alles vorhandene nicht kompatibel zw. den Delphi Versionen ist. Der Record ist auch sehr einfach, ein paar einfache Integers und Strings. SizeOf liefert auf beiden Seiten das gleiche Ergebnis. Der Record wird auf Dll Seite allokiert und dann in die Liste eingehängt. Beide Units die von D7 und D3 verwendet werden (Liste und Definition vom Record) lassen sich in beiden problemlos kompilieren. Trotzdem gibt es beim freigeben der Liste (D3 Seite, nach der Datenübertragung die sogar klappt!) eine Exception (und dann noch n paar mehr :P). Da das jetzt schon so gut funktioniert hat Frage ich mich woran das liegen könnte. Debuggen ist Schwer. Entweder es geht nur D3 oder D7 :/ Eine andere Möglichkeit zum Datenübertragen die mir einfällt wäre File I/O aber das würde ich gern vermeiden. Hier mal die Liste
Delphi-Quellcode:
unit LinkList;
interface type PLinkListItem = ^TLinkListItem; TLinkListItem = record Next: PLinkListItem; Data: Pointer; end; TLinkList = class private FAnchor: PLinkListItem; function GetItem(AIndex: Integer): PLinkListItem; function GetItemData(AIndex: Integer): Pointer; public constructor Create; destructor Destroy; override; property Items[Index: Integer]: Pointer read GetItemData; default; procedure Add(AItem: Pointer); procedure Clear; function Count: Integer; end; implementation { LinkList } constructor TLinkList.Create; begin inherited; FAnchor := nil; end; destructor TLinkList.Destroy; begin Clear; inherited; end; procedure TLinkList.Add(AItem: Pointer); var ANewItem: PLinkListItem; begin New(ANewItem); ANewItem^.Data := AItem; ANewItem^.Next := nil; if not Assigned(FAnchor) then FAnchor := ANewItem else GetItem(Count-1)^.Next := ANewItem; end; function TLinkList.Count: Integer; var AItem: PLinkListItem; begin result := 0; AItem := FAnchor; while Assigned(AItem) do begin Inc(result); AItem := AItem.Next; end; end; function TLinkList.GetItem(AIndex: Integer): PLinkListItem; var CurrIdx: Integer; begin result := FAnchor; CurrIdx := 0; while Assigned(result) AND (CurrIdx < AIndex) do begin Inc(CurrIdx); result := TLinkListItem(result^).Next; end; if (CurrIdx <> AIndex) OR (not Assigned(result)) then result := nil; end; function TLinkList.GetItemData(AIndex: Integer): Pointer; begin result := GetItem(AIndex); if Assigned(result) then result := TLinkListItem(result^).Data; end; procedure TLinkList.Clear; var ANext, AItem: PLinkListItem; begin AItem := FAnchor; while Assigned(AItem) do begin ANext := AItem^.Next; Dispose(AItem); AItem := ANext; end; end; |
Re: Datenaustausch zw. DLL und Applikation
Was verhindert, dass du dein D3-Projekt auf D7 migrierst?
|
Re: Datenaustausch zw. DLL und Applikation
bde, 1000000 zeilen, inkompatibilitäten, fehlende klassen,... das thema steht nicht zur debatte
|
Re: Datenaustausch zw. DLL und Applikation
Den Record als packed record und die Liste als Interface sollten es dir ermöglichen den gleichen Code (für Record, Classe und Interface) in beiden Delphi versionen zu benutzen. Da Delphi-Interfaces immer COM-interfaces[1] sind und packed Records keine Alignment-Ärgereien machen dürften[2], würde ich davon ausgehen, dass du sie einfach in exportierten Funktionen der DLL ein- und ausgeben kannst.
[1]müssen gleich sein, da sich an COM seit damals wohl nix geändert hat ;) [2]müssen auch kompatibel sein, da das nunmal der Weg ist um Strukturen an non-Delphi-Sprachen zu übergeben. |
Re: Datenaustausch zw. DLL und Applikation
nur zum verständnis:
ich definier die liste als interface und implementier dann die funktionen jeweils auf d3/d7 seite (eigentlich sollte ja auch wieder der gleiche code gehn). und als mein var listen-parameter übergeb ich die instanz die das interface implementiert? das mit den packed records wusst ich zwar eigentlich, hatte's aber nicht gemacht :wall: :P werd ich mal probieren danke für den tipps! |
Re: Datenaustausch zw. DLL und Applikation
:( Also es funktioniert leider nicht wie ichs jetzt probier habe:
mit den methoden der obigen liste hab ich ein interface deklariert (ILinkList) die liste (TLinkList) erbt dann von ILinkList und gezwungener maßen von TInterfacedObject als dll funktion parameter übergeb ich ein pointer auf eine TLinkList (PLinkList = ^TLinkList) hatte ich das so richtig verstanden elvis? die adresse vom parameter ist auch auf beiden seiten identisch aber schon der anchor ist dann unterschiedlich :( die delaration der funktion schaut so aus (beide seiten ;))
Delphi-Quellcode:
aufruf d3 seite
procedure GetStruct(ALinkList: PLinkList); stdcall;
Delphi-Quellcode:
verarbeitung dll/d7
var AStruct: TLinkList
begin AStruct := TLinkList.Create; try GetStruct(PLinkList(@AStruct)); ...irgendwas mit den daten machen... finally AStruct.free; end; end;
Delphi-Quellcode:
was mach ich falsch? :|
procedure GetStruct(ALinkList: PLinkList); stdcall;
begin if Assigned(ALinkList) then begin ALinkList^.Clear; ALinkList^.Add(NewElement); ... end; end; |
Re: Datenaustausch zw. DLL und Applikation
Zitat:
Deshalb deshalb glaube ich nicht das es erlaubt ist zwischen unterschiedlichen Delphi-Versionen interfaces zwischen Exe und DLL auszutauchen. Ich denke hier gibt es die gleichen Probleme wie mit "richtigen" Referenzen. Wenn Du unterschiedliche Versionen von Delphi in Exe und DLL einsetzen willst bleibt dir nichts übrig als nur das zu nehmen was jede andere nicht Delphi-Sprache auch versteht. Eine C-Kompatible schnittstelle. Und wie du schon geschrieben hast willst Du auch Strings übertragen. Und da wird es krachen. Du wirst auf PChar's umsteigen müssen damit es klappt (Ich glaube nicht das Sharemem von D3 (gab das damals schon?) mit Sharemem von D7 kompatible ist. |
Re: Datenaustausch zw. DLL und Applikation
Delphi3-Objecte sind inkompatibel zu Delphi7-Objecten. Von daher geht es nicht das du eine in Delphi3 erzeugte TLinklist mit Delphi7 befüllst.
|
Re: Datenaustausch zw. DLL und Applikation
ja scheint wohl leider so zu sein.
ich hab ja auch kein problem damit pchars zu verwenden bloß diese relativ komplexen strukturen alle innerhalb von einem oder mehreren pchars zu übertragen gefällt mir nicht :| dann werd ich wohl doch mal mit file i/o experementieren. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16: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 by Thomas Breitkreuz