Avatar billede ugge Nybegynder
27. marts 2001 - 20:03 Der er 9 kommentarer og
1 løsning

streaming af objekt

Hej.

Jeg kunne godt tænke mig at se en stump kode der kan lave et objekt om til en \':array of byte\' eller lignende.

Det er ikke nødvendigt at inkludere objektets objektreferencer, men det er nødvendigt at inkludere longstrings.

Formålet er at konvertere objektet til en bytestream, kryptere det (DSE eller GOST måske), caste det til en Widestring, sende objektet til en anden computer via DCOM (som accepterer widestrings...), caste det tilbage, dekryptere det, trylle det om til et objekt igen og voila.

På forhånd tak....
Avatar billede nico26 Nybegynder
27. marts 2001 - 23:00 #1
Du kan prøve det her. Tricket er at man bruger den teknik delphi bruger når den gemmer componenter på en form i en dfm fil. Du skal bare lade dine objecter nedarve fra TComponent, og for de attributter du vil gemme, laver du en published property, da det kun er published properties som delphi streamer.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    FComp: string;
  public
    { Public declarations }
  end;

  TMyComp = class(TComponent)
  private
    FText: string;
  published
    property Text: string read FText write FText;
  end;

var
  Form1: TForm1;

implementation

uses
  Unit2;

{$R *.DFM}

function ComponentToString(Component: TComponent): string;
var
  BinStream: TMemoryStream;
  StrStream: TStringStream;
  s: string;
begin
  BinStream := TMemoryStream.Create;
  try
    StrStream := TStringStream.Create(s);
    try
      BinStream.WriteComponent(Component);
      BinStream.Seek(0, soFromBeginning);
      ObjectBinaryToText(BinStream, StrStream);
      StrStream.Seek(0, soFromBeginning);
      Result := StrStream.DataString;
    finally
      StrStream.Free;
    end;
  finally
    BinStream.Free;
  end;
end;

function StringToComponent(Value: string): TComponent;
var
  StrStream: TStringStream;
  BinStream: TMemoryStream;
begin
  StrStream := TStringStream.Create(Value);
  try
    BinStream := TMemoryStream.Create;
    try
      ObjectTextToBinary(StrStream, BinStream);
      BinStream.Seek(0, soFromBeginning);
      Result := BinStream.ReadComponent(nil);
    finally
      BinStream.Free;
    end;
  finally
    StrStream.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  C: TMyComp;
begin
  RegisterClass(TMyComp);
  C := TMyComp.Create(Application);
  C.Text := \'Hello\';
  FComp := ComponentToString(C);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  C: TMyComp;
begin
  C := StringToComponent(FComp) as TMyComp;
  ShowMessage(C.Text);
end;

/nico
Avatar billede ugge Nybegynder
27. marts 2001 - 23:28 #2
Den løsning var jeg nu godt klar over, og jeg finder det lidt utilfredsstilende at nedarver fra TComponent. Bl.a. er det mit indtryk at metoden ikke streamer effektivt, dvs der kommer mange redundante bytes. Er det ikke rigtigt?
Avatar billede nico26 Nybegynder
27. marts 2001 - 23:33 #3
hmm. det er nok ikke verdens pæneste løsning, med hvad havde du egentligt forestillet dig som alternativ?
Avatar billede ugge Nybegynder
27. marts 2001 - 23:54 #4
Tjahh, I C ville jeg bruge memcopy til at kopiere attributterne over i en streng som jeg så ville caste til [hvadsomhelst]. Dette er selfølgelig heller ikke ligefrem pænt, men det er effektivt, virker og er simpelt. Helt så simpelt er det ikke i Delphi bl.a. pga. longstringformatet. Jeg ved ikke rigtigt hvad jeg skal gøre hmmmm, jeg kunne jo også bruge ShortStrings / PChar. Eller hvad?
Avatar billede ugge Nybegynder
27. marts 2001 - 23:55 #5
Hov hvad nu?
Avatar billede borrisholt Novice
28. marts 2001 - 07:39 #6
ugge  >> \"Tjahh, I C ville jeg....\" hvorfor ikke bare gøre det samme i Pascal ?

Jens B
Avatar billede martinlind Nybegynder
28. marts 2001 - 09:26 #7
Eller lave nogle forsøg, det går rent faktisk temmelig hurtig med comp. streamming, så måske dinne fornemmelser ikke holder stik, du kan foresten nøjes med TPersistent da det er i den klasse delphi impl. Streamming.
Avatar billede ugge Nybegynder
28. marts 2001 - 10:54 #8
Tak for hjælpen alle,  jeg tror jeg benytter streameren uden den dyre ObjectTextToBinary, det skulle være muligt. Det viser sig at mine objekter alligevel bliver mindre end TCP/IP pakkestørrelsen, så det gør ikke så meget hvis der er nogle redundante bytes...

borrisholt,

Fordi jeg ikke kan greje longstringformatet :-)
Avatar billede borrisholt Novice
28. marts 2001 - 10:57 #9
ugge >> så lad være med at bruge det ... brug er array of byte eller en pChar. hvis du skal streame noget \"i dag\" så skal du ikke bruge en long string.

Jens B
Avatar billede martinlind Nybegynder
28. marts 2001 - 11:17 #10
ugge >> Det funker fint med rent binær stream, jeg har lavet en lille OBJ-base på den måde uden problemer, og skal der nye felter på ændrer jeg bare DB-klassen så tilretter resten sig selv, vha. RTTI, det er faktisk lidt sødt efter min smag, og dejligt flexsibelt.

/Martin
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester