Konuyu Oyla:
  • Derecelendirme: 5/5 - 2 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Variant To TBytes
#1
+4 puan değerinde küçük bir soru yöneltiyorum arkadaşlarıma. Doğru cevap veren tüm arkadaşlara +4 puan vereceğim.(Daha fazla puan verilemediği için)

Elimizde bulunan Variant tipli bir değişkenin TBytes'a dönüştürülmesi istenen. Örneğin;


var
  V : Variant;
  I  :  Integer;
begin
  I := 1453;
  V := I;
  // Elde edilecek byte dizisi [5, 173, 0, 0]
end;

var
  V : Variant;
  S :  AnsiString;
begin
  S := 'DELPHI';
  V := S;
  // Elde edilecek byte dizisi [68, 69, 76, 80, 72, 73]
end;

Kolay gelsin Wink

Not: Unutulmaması gereken şey, Variant tipli değişkenimize her türden veri türünü atayabileceğimiz. Bu durumda elde edilmesi gereken byte dizisinin uzunluğunun atanan veri türünün size'ı ile eşit olması gerektiğidir. Örneğin 4 Byte'lık Integer veri türü için Byte array'de 4 adet eleman olmalıdır, Word türlü bir değişken için Byte array'de 2 eleman olmalıdır. "HELLO WORLD" string'i için Byte array'de 11 eleman olmalıdır gibi.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#2
Tuğrul Bey, Pointer kullanımı serbest mi Smile
Cevapla
#3
(09-08-2017, Saat: 12:13)Abdullah Ilgaz Adlı Kullanıcıdan Alıntı: Tuğrul Bey, Pointer kullanımı serbest mi Smile

Tabi tabi, herşey serbest Smile
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#4
var
  V : Variant;
  S :  AnsiString;
  lvBytes : TBytes;
begin
  S := 'HELLO WORLD';
  V := S;
  lvBytes := TEncoding.UTF8.GetBytes(V);
end;
O. Mert
WWW
Cevapla
#5
var
x : integer;
v : Variant;
deger : String;
ba : array of Byte;
s : String;
begin
deger := 'NEJAT';
v := deger;
s := String(v);
SetLength(ba, Length(s));
for x := 1 to Length(s) do
    ba[x] := Ord(s[x]);
end;
WWW
Cevapla
#6
(09-08-2017, Saat: 13:26)esistem Adlı Kullanıcıdan Alıntı:
var
x : integer;
v : Variant;
deger : String;
ba : array of Byte;
s : String;
begin
deger := 'NEJAT';
v := deger;
s := String(v);
SetLength(ba, Length(s));
for x := 1 to Length(s) do
    ba[x] := Ord(s[x]);
end;

String -> Byte Array değil üstad. Variant -> Byte array olacak ;-)
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#7
var
 Form2: TForm2;
 I: Integer;
 S: AnsiString;
 W: Word;

 V: Variant;
 P: PByte;
 Arr: TBytes;

 VData: PVarData;

implementation

{$R *.dfm}

procedure TForm2.FormCreate(Sender: TObject);
begin
 S := 'HELLO WORLD';
 I := 1453; // [5, 173, 0, 0]
 W := 31;

 V := I;

 VData := @TVarData(V);

 if VData^.VType = varInteger then
 begin
   SetLength(Arr, SizeOf(Integer));
   P := PByte(@VData^.VInteger);
   Arr[0] := P^;

   Inc(P);
   Arr[1] := P^;

   Inc(P);
   Arr[2] := P^;

   Inc(P);
   Arr[3] := P^;
 end;

 if VData^.VType = varWord then
 begin
   SetLength(Arr, SizeOf(Word));

   P := PByte(@VData^.VWord);
   Arr[0] := P^;

   Inc(P);
   Arr[1] := P^;
 end;

 if VData^.VType = varString then
 begin
   P := PByte(@VData^.VString);
   //??????
 end;

end;
Cevapla
#8
(09-08-2017, Saat: 15:56)compute Adlı Kullanıcıdan Alıntı:
var
 Form2: TForm2;
 I: Integer;
 S: AnsiString;
 W: Word;

 V: Variant;
 P: PByte;
 Arr: TBytes;

 VData: PVarData;

implementation

{$R *.dfm}

procedure TForm2.FormCreate(Sender: TObject);
begin
 S := 'HELLO WORLD';
 I := 1453; // [5, 173, 0, 0]
 W := 31;

 V := I;

 VData := @TVarData(V);

 if VData^.VType = varInteger then
 begin
   SetLength(Arr, SizeOf(Integer));
   P := PByte(@VData^.VInteger);
   Arr[0] := P^;

   Inc(P);
   Arr[1] := P^;

   Inc(P);
   Arr[2] := P^;

   Inc(P);
   Arr[3] := P^;
 end;

 if VData^.VType = varWord then
 begin
   SetLength(Arr, SizeOf(Word));

   P := PByte(@VData^.VWord);
   Arr[0] := P^;

   Inc(P);
   Arr[1] := P^;
 end;

 if VData^.VType = varString then
 begin
   P := PByte(@VData^.VString);
   //??????
 end;

end;

Güzel başlangıç. Biraz daha uygulanabilir hâle getirebilirsiniz ;-)
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#9
Evet hocam daha generic bir kodlama yapsaymışım daha iyi olurmuş aslında.
Şuradaki açıklamayı okuyarak yaptım.
Alıntı:Description
The TVarData record is Delphi’s implementation of the Variant type. You can cast any Variant to TVarData to examine the internal workings of the Variant.

The VType field stores the variant type (as returned by VarType). The other fields store type-specific information. Values up to 8 bytes in size are stored directly in the TVarData record. Larger items are stored separately; the TVarData record holds a pointer to the actual data (such as VArray, which points to a TVarArray record).
Buradan anladığım Variant tipinin implementasyonu TVarData record tipi ile gerçekleşmiş.

8 Byte'a kadar bilgi tutan veri tipleri doğrudan TVarData içinde tutuluyor iken, daha büyük veri tutabilen tipteki verilerin sadece adresi(pointer) tutuluyormuş.

Yani Variant tipindeki değişkene, array string gibi bir değişken ataması (assignment statement) yaparsam eğer, bunların değerleri yerine adresleri tutuluyor.

Stringin byte'larını okuma kısmını yapamadım. :ss
Cevapla
#10
Eğer VType'ın varString olduğunu bulduysanız tek yapmanız gereken Variant->String dönüşümü. Zaten bunun için dönüşüm yapmanıza gerek yok. Variant değeri direk string değişkene aktarabilirsiniz. Yalnız dikkat edin, varString dışında string tipleri de var: varUString, varOleStr...
There's no place like 127.0.0.1
WWW
Cevapla




Konuyu Okuyanlar: 1 Ziyaretçi