Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Datasnap - Ung. Zeigeroperation bei Rückgabe eines Objektes (https://www.delphipraxis.net/168908-datasnap-ung-zeigeroperation-bei-rueckgabe-eines-objektes.html)

RedOne 18. Jun 2012 09:48

Datasnap - Ung. Zeigeroperation bei Rückgabe eines Objektes
 
Hallo Forum

Datasnap ist schon ne tolle Sache, hat aber auch seine Tücken.
Auf dem Client hole ich mittels Datasnap ein einfaches Objekt. Dieses muss ich nicht freigeben, Datasnap übernimmt dies.
Wenn ich das gleiche Objekt nun dem Server wieder zusende, erhalte ich beim Beenden der Anwendung eine Ungültige Zeigeroperation, vermutl. weil Datasnap das Objekt zweimal freigeben möchte.

Server

Delphi-Quellcode:
type
  {$METHODINFO ON}
  TMyClass = class(TComponent)
    function GetTransport: TSendeMich;
    procedure SetTransport( _obj: TSendeMich );
  end;
  {$METHODINFO OFF}

implementation

{ TMyClass }

function TMyClass.GetTransport: TSendeMich;
begin
  Result:= TSendeMich.Create;
  Result.A:= 3;
  Result.B:= 1;
end;

procedure TMyClass.SetTransport(_obj: TSendeMich);
begin
  {}
end;
Client
Delphi-Quellcode:
procedure TForm1.ButtonCalcClick(Sender: TObject);
var
  Temp: TMyClassClient;
  SendeMich: TSendeMich;
begin
  Temp:= TMyClassClient.Create(SQLConnection1.DBXConnection);
  try
    SendeMich:= temp.GetTransport;
    temp.SetTransport( SendeMich ); //ohne dieser Funktion wird keine Exception geworfen
  finally
    temp.Free;
  end;
end;
Gibt es einen analogen "OwnsObject"-Parameter, damit Datasnap weiss, dass dieses Objekt nicht zerstört werden muss?

Herzlichen Dank

RedOne

himitsu 18. Jun 2012 10:22

AW: Datasnap - Ung. Zeigeroperation bei Rückgabe eines Objektes
 
Wie sieht denn TMyClassClient aus?

Man kann teilweise steuern, ob DataSnap was automatisch freigeben soll, oder nicht.
Für Streams wird da z.B. ein Property in die automatisch generierten Klassen eingebaut.

RedOne 18. Jun 2012 13:01

AW: Datasnap - Ung. Zeigeroperation bei Rückgabe eines Objektes
 
Die automatisch erzeugte Klasse TMyClassClient sieht folgend aus:

Delphi-Quellcode:
//
// Erzeugt vom DataSnap-Proxy-Generator.
// 18.06.2012 14:00:32
//

unit DataSnapUnits;

interface

uses Data.DBXCommon, Data.DBXClient, Data.DBXDataSnap, Data.DBXJSON, Datasnap.DSProxy, System.Classes, System.SysUtils, Data.DB, Data.SqlExpr, Data.DBXDBReaders, TransportUnits, Data.DBXJSONReflect;

type
  TMyClassClient = class(TDSAdminClient)
  private
    FGetTransportCommand: TDBXCommand;
    FSetTransportCommand: TDBXCommand;
  public
    constructor Create(ADBXConnection: TDBXConnection); overload;
    constructor Create(ADBXConnection: TDBXConnection; AInstanceOwner: Boolean); overload;
    destructor Destroy; override;
    function GetTransport: TSendeMich;
    procedure SetTransport(_obj: TSendeMich);
  end;

implementation

function TMyClassClient.GetTransport: TSendeMich;
begin
  if FGetTransportCommand = nil then
  begin
    FGetTransportCommand := FDBXConnection.CreateCommand;
    FGetTransportCommand.CommandType := TDBXCommandTypes.DSServerMethod;
    FGetTransportCommand.Text := 'TMyClass.GetTransport';
    FGetTransportCommand.Prepare;
  end;
  FGetTransportCommand.ExecuteUpdate;
  if not FGetTransportCommand.Parameters[0].Value.IsNull then
  begin
    FUnMarshal := TDBXClientCommand(FGetTransportCommand.Parameters[0].ConnectionHandler).GetJSONUnMarshaler;
    try
      Result := TSendeMich(FUnMarshal.UnMarshal(FGetTransportCommand.Parameters[0].Value.GetJSONValue(True)));
      if FInstanceOwner then
        FGetTransportCommand.FreeOnExecute(Result);
    finally
      FreeAndNil(FUnMarshal)
    end
  end
  else
    Result := nil;
end;

procedure TMyClassClient.SetTransport(_obj: TSendeMich);
begin
  if FSetTransportCommand = nil then
  begin
    FSetTransportCommand := FDBXConnection.CreateCommand;
    FSetTransportCommand.CommandType := TDBXCommandTypes.DSServerMethod;
    FSetTransportCommand.Text := 'TMyClass.SetTransport';
    FSetTransportCommand.Prepare;
  end;
  if not Assigned(_obj) then
    FSetTransportCommand.Parameters[0].Value.SetNull
  else
  begin
    FMarshal := TDBXClientCommand(FSetTransportCommand.Parameters[0].ConnectionHandler).GetJSONMarshaler;
    try
      FSetTransportCommand.Parameters[0].Value.SetJSONValue(FMarshal.Marshal(_obj), True);
      if FInstanceOwner then
        _obj.Free
    finally
      FreeAndNil(FMarshal)
    end
    end;
  FSetTransportCommand.ExecuteUpdate;
end;


constructor TMyClassClient.Create(ADBXConnection: TDBXConnection);
begin
  inherited Create(ADBXConnection);
end;


constructor TMyClassClient.Create(ADBXConnection: TDBXConnection; AInstanceOwner: Boolean);
begin
  inherited Create(ADBXConnection, AInstanceOwner);
end;


destructor TMyClassClient.Destroy;
begin
  FreeAndNil(FGetTransportCommand);
  FreeAndNil(FSetTransportCommand);
  inherited;
end;

end.

RedOne 18. Jun 2012 13:02

AW: Datasnap - Ung. Zeigeroperation bei Rückgabe eines Objektes
 
Ahh, ich seh schon... der Konstruktur :-)
Ja, dass funktioniert :)

Merci!


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:31 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz