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
).
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;