Konuyu Oyla:
  • Derecelendirme: 5/5 - 2 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Variant To TBytes
#11
O zaman veri tipini varianttan çevirdikten sonra case of ile ebatı doğrultusunda elimize alıp işaretleyebiliriz.

    var
        V: Variant;
        P: Pointer;
        S: Integer;
    begin
        V := 'DELPHI';
        case VarType(V) of
            varShortInt:
                begin
                    P := @V.VShortInt;
                    S := SizeOf(ShortInt);
                end;
            varByte:
                begin
                    P := @V.VByte;
                    S := SizeOf(Byte);
                end;
            varSmallint:
                begin
                    P := @V.VSmallInt;
                    S := SizeOf(Smallint);
                end;
            varWord:
                begin
                    P := @V.VWord;
                    S := SizeOf(Word);
                end;
            varInteger:
                begin
                    P := @V.VInteger;
                    S := SizeOf(Integer);
                end;
            varLongWord:
                begin
                    P := @V.VLongWord;
                    S := SizeOf(LongWord);
                end;
            varString:
               begin
                    P := @V.VString;
                    S := SizeOf(String);
               end;
            varUString:
              begin
                   P := @V.UString;
                   S := SizeOf(UnicodeString);
              end;
            // gösterim...
        end;
    end;
Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.
Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.
Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.
Cevapla
#12
(09-08-2017, Saat: 23:11)SimaWB Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.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...
Evet hocam ya dikkatimden kaçmış onlar.Pascal'da yeni sayılırım daha.
  
var
 A_S: AnsiString;
 U_S: UnicodeString;
begin  
  if VData^.VType = varString then
  begin
    A_S := PAnsiString(@VData^.VString)^;
    // to do
  end;

  if VData^.VType = varUString then
  begin
    U_S := PUnicodeString(@VData^.VUString)^;
    // to do
  end;
end;

Cevapla
#13
SizeOf bazı veri tiplerinde doğru sonucu vermez bilginize...
P.Safa:Yaşlanarak değil, yaşayarak tecrübe kazanılır.Zaman insanları değil,armutları olgunlaştırır
C.Yücel:Toprak gibi olmalısın! Ezildikçe sertleşmelisin!Seni ezenler sana muhtaç kalmalı! Hayatı sende bulmalı
S.Canan:Bildiğini zannettiğin an hiç bir şey öğrenemezsin
Bilgi uçar
WWW
Cevapla
#14
Merhaba ,
VarArrayHighBound ve VarArrayLowBound fonsiyonları verilen variant ın tipini algılayıp maksimum ve minimum boyutları vermiyor muydu ? işinize yarayabilir.
Cevapla
#15
(10-08-2017, Saat: 15:56)vkamadan Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.Merhaba ,
VarArrayHighBound ve VarArrayLowBound  fonsiyonları verilen variant ın tipini algılayıp  maksimum ve minimum boyutları vermiyor muydu ? işinize yarayabilir.

Bu metodların işe yarayabilmesi (hata vermemesi için) Variant data'da bir array olmalıdır. Primitive veri türlerinde hata vermesi gerekiyor, eğer yanlış hatırlamıyor isem.

(10-08-2017, Saat: 14:07)uparlayan Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.SizeOf bazı veri tiplerinde doğru sonucu vermez bilginize...

Neden ?
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#16
Hocam ben bu kadar uygulanabilir hale getirdim. Devamını başka arkadaşlara devredip kaçıyorum.
function GetBytesOfVariant(Value: Variant): TBytes;
var
 I: Integer;
 P: PByte;
 PLast: PByte;
 VData: PVarData;
begin
 VData := @TVarData(Value);

 if VData^.VType = varInteger then
 begin
   SetLength(Result, SizeOf(Integer));
   P := PByte(@VData^.VInteger);
   PLast := P + Byte(SizeOf(Integer));
 end;

 if VData^.VType = varWord then
 begin
   SetLength(Result, SizeOf(Word));
   P := PByte(@VData^.VWord);
   PLast := P + Byte(SizeOf(Word));
 end;

  if VData^.VType = varString then
 begin
   //to do
 end;

 if VData^.VType = varUString then
 begin
   //to do
 end;


 I := 0;
 while P <= PLast do
 begin
   Result[I] := P^;
   Inc(P);
   Inc(I);
 end;

end;
Cevapla
#17
(10-08-2017, Saat: 16:06)uparlayan Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.SizeOf bazı veri tiplerinde doğru sonucu vermez bilginize...
Neden ?

Çünkü;

SizeOf, bir değişkenin veya type'in bayt cinsinden depolama boyutunu verir.

Length ise bir dizinin veya stringin karakter sayısını verir.

Aradaki farkı aşağıdaki örnek kod parçacığından da test edebilirsiniz;

procedure TForm1.Button1Click(Sender: TObject);
var
 S: String;
begin
 S := 'ali veli';
 Memo1.Clear;
 memo1.Lines.Add(SizeOf(S).ToString); // 4
 memo1.Lines.Add(Length(S).ToString); // 8
end;

Bu konunun uzmanı değilim, böyle bir sorunun sorulmuş olmasını da açıkçası olumlu buluyorum, zira bu tarz kaliteli sorular çoğaldıkça insanın feyz alması başka bir keyif veriyor. 

Ben olaya biraz daha farklı bakıp, variant değişkenin bir dizi olması durumunda bunun TByte cinsinden nasıl toplanabileceği ile ilgili farklı bir örnek kod paylaşmak istiyorum, (dediğim gibi fazla bir bilgim yok, o nedenle beni fazla hırpalamayın lütfen   Big Grin   )

( Aşağıdaki kodu spagetti bulabilirsiniz, bazı veri tipleri için tam olarak bitmediğini de ifade etmek lazım, mazur görün lütfen. )

unit Unit1;

interface

uses
 Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
 Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Data.DB, Datasnap.DBClient,
 SynEdit, SynMemo;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Memo1: TSynMemo;
   Button2: TButton;
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;
 TByteArr = TBytes; // veya aşağıdaki gibi
 //TByteArr = array of Byte;

var
 Form1: TForm1;

implementation

{$R *.dfm}

function StrToByte(const Value: String): TByteArr;
var
 I   : Integer;
 Ebat: Integer;
begin
 Ebat := Length(Value);
 SetLength(Result, Ebat);
 for I := 0 to Ebat - 1 do Result[I] := ord(Value[I + 1]);
end;

function ByteToByte(const Value: Byte): TByteArr;
begin
 SetLength(Result, 1);
 Result[0] := TByteArr(@Value)[ 0 ];
end;

function IntToByte(const Value: Integer): TByteArr;
var
 I : Integer;
begin
 SetLength(Result, 4);
 for I := 0 to 3 do Result[I] := TByteArr(@Value)[ I ];
end;

function WordToByte(const Value: Word): TByteArr;
begin
 SetLength(Result, 2);
 Result[0] := TByteArr (@Value) [ 0 ];
 Result[1] := TByteArr (@Value) [ 1 ];
end;

function LongWordToByte(const Value: LongWord): TByteArr;
var
 I : Integer;
begin
 SetLength(Result, 4);
 for I := 0 to 3 do Result[I] := TByteArr(@Value)[I];
end;

function Int64ToByte(const Value: Int64): TByteArr;
var
 I : Integer;
 Ebat: Integer;
begin
 Ebat := SizeOf(Value);
 SetLength(Result, Ebat);
 for I := 0 to Ebat - 1 do Result[I] := TByteArr(@Value)[I];
end;

function VarToByte(const Value: Variant; var BaytSayisi: Integer): TByteArr;
var
 Ebat, EkEbat: Integer;
 Miktar      : Integer;
 Pointer     : PVariant;
 I, J, Q, W  : Integer;
 VeriTipi    : Integer;
 Eklenti     : TByteArr;
 W64         : Int64;
 Wrd         : Word;
 LW          : LongWord;
 S: String;
begin
 if (VarIsArray(Value) = TRUE) then begin
     //  Diziyi kilitleyip, gerçek değerleri tutan belleğe işaretçi koyuyoruz, bu anlamda aslında bu tıpkı SQL'de CURSOR kullanmaya benziyor...
     Pointer   := VarArrayLock(Value);
     //  Dizinin ilk bakıştaki uzunluğunu elde ediyoruz, bazı veri tipleri veriy yerine adresi tuttuğu için bu böyle...
     Ebat      := VarArrayHighBound(Value, 1) - VarArrayLowBound(Value, 1) + 1;
     //  Sonuç kümesinin boyunu parametremizdekiyle eşitliyoruz, ki zaten devamında bu kısım genişleyecek ama şimdilik bu böyle...
     SetLength(Result, Ebat);
     J := 0; // Sonuç kümesindeki bayt sayısını bununla takip edeceğiz...
     Miktar := Ebat; // Bu aslında varyant dizinin eleman sayısını veriyor...
     for I := 0 to Miktar - 1 do begin  //  Variant Dizinin her bir elemanı üzerinde tek tek tarama yapıyoruz...
         VeriTipi := VarType(Pointer^);
         case VeriTipi of
               varBoolean    : begin
                                 Result[J] := Pointer^;
                                 Inc(J);
                               end;
               varByte       : begin
                                 Result[J] := Pointer^;
                                 Inc(J);
                               end;
               varSmallInt   ,
               varWord       : begin
                                 Wrd     := Pointer^;
                                 EkEbat  := SizeOf(Wrd); // Buna da Dikkat !
                                 SetLength(Eklenti, EkEbat);
                                 Eklenti := WordToByte(Wrd);
                                 Ebat    := Ebat + EkEbat - 1;
                                 SetLength(Result, Ebat);
                                 for Q := 0 to EkEbat - 1 do begin
                                     Result[J] := Eklenti[Q];
                                     Inc(J);
                                 end;
                               end;
               varLongWord   : begin
                                 Wrd     := Pointer^;
                                 EkEbat  := SizeOf(Wrd); // Buna da Dikkat !
                                 SetLength(Eklenti, EkEbat);
                                 Eklenti := LongWordToByte(Wrd);
                                 Ebat    := Ebat + EkEbat - 1;
                                 SetLength(Result, Ebat);
                                 for Q := 0 to EkEbat - 1 do begin
                                     Result[J] := Eklenti[Q];
                                     Inc(J);
                                 end;
                               end;
               varSingle     ,
               varDouble     ,
               varCurrency   : begin
                                 // araştırma konusu...
                               end;

               varOleStr     ,
           //  varStrArg     ,
           //  varObject     ,
               varUStrArg    ,
           //  varAny        ,
               varUString    ,
               varString     : begin
                                 S       := Pointer^;
                                 EkEbat  := Length(S); // Dikkat !
                                 SetLength(Eklenti, EkEbat);
                                 Eklenti := StrToByte(S);
                                 Ebat    := Ebat + EkEbat - 1;
                                 SetLength(Result, Ebat);
                                 for Q := 0 to EkEbat - 1 do begin
                                     Result[J] := Eklenti[Q];
                                     Inc(J);
                                 end;
                               end;
               varInteger    : begin
                                 W     := Pointer^;
                                 EkEbat  := SizeOf(W); // Buna da Dikkat !
                                 SetLength(Eklenti, EkEbat);
                                 Eklenti := IntToByte(W);
                                 Ebat    := Ebat + EkEbat - 1;
                                 SetLength(Result, Ebat);
                                 for Q := 0 to EkEbat - 1 do begin
                                     Result[J] := Eklenti[Q];
                                     Inc(J);
                                 end;
                               end;
               varInt64      : begin
                                 W64     := Pointer^;
                                 EkEbat  := SizeOf(W64); // Buna da Dikkat !
                                 SetLength(Eklenti, EkEbat);
                                 Eklenti := Int64ToByte(W64);
                                 Ebat    := Ebat + EkEbat - 1;
                                 SetLength(Result, Ebat);
                                 for Q := 0 to EkEbat - 1 do begin
                                     Result[J] := Eklenti[Q];
                                     Inc(J);
                                 end;
                               end;
         end;
         Inc(Pointer); //  Sonraki elemanına geçiyoruz
     end;
     VarArrayUnlock(Value);    //  Dizinin kilidini açıyoruz...
     BaytSayisi := J;
 end else begin
 end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 ba: TByteArr;
 I: Integer;
 V: Variant;
 vava: array of Variant;
 X: Integer;
 function iif(aBoolean: Boolean; aTrue: string; aFalse: String): String;
 begin
   if aBoolean then Result := aTrue else Result := aFalse;
 end;
begin
 Memo1.Lines.Clear;
 V := Variant('abuzer kadayıf');
 vava := [ Byte(3)
          , V
          , Integer(1453)
          , SmallInt(1453)
          , Int64(1071)
          , word(65537)     // 256x256=65536 !
          , AnsiString('AAA')
          , String('BBB')
          , WideString('CCC')
          ];
 ba := VarToByte(Vava, X);
 for I := Low(ba) to High(ba) do begin
      Memo1.Lines.Add( IntToHex( ba[I], 4)
                     + ' '
                     + iif(ba[I] > 31, Chr(ba[I]), ' ' )
                     + ' (' + ba[I].ToString + ')'
                     );
 end;
 Memo1.Lines.Add('Bayt Sayısı = ' + X.ToString);
 SetLength(ba, 0);
 //FreeAndNil(ba);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
 S: String;
begin
 S := 'ali veli';
 Memo1.Clear;
 memo1.Lines.Add(SizeOf(S).ToString); // = 4
 memo1.Lines.Add(Length(S).ToString);  // = 8
end;

end.


Ek Dosyalar Resimler
   
P.Safa:Yaşlanarak değil, yaşayarak tecrübe kazanılır.Zaman insanları değil,armutları olgunlaştırır
C.Yücel:Toprak gibi olmalısın! Ezildikçe sertleşmelisin!Seni ezenler sana muhtaç kalmalı! Hayatı sende bulmalı
S.Canan:Bildiğini zannettiğin an hiç bir şey öğrenemezsin
Bilgi uçar
WWW
Cevapla
#18
(10-08-2017, Saat: 19:19)uparlayan Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.SizeOf, bir değişkenin veya type'in bayt cinsinden depolama boyutunu verir.
procedure TForm1.Button1Click(Sender: TObject);
var
 S: String;
begin
 S := 'ali veli';
 Memo1.Clear;
 memo1.Lines.Add(SizeOf(S).ToString); // 4
 memo1.Lines.Add(Length(S).ToString); // 8
end;

Bu olayı anlamadım, S değişkenini bellekte nasıl 4 byte alana sığdırırz ?
Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.
WWW
Cevapla
#19
(11-08-2017, Saat: 09:19)esistem Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.
(10-08-2017, Saat: 19:19)uparlayan Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.SizeOf, bir değişkenin veya type'in bayt cinsinden depolama boyutunu verir.
procedure TForm1.Button1Click(Sender: TObject);
var
 S: String;
begin
 S := 'ali veli';
 Memo1.Clear;
 memo1.Lines.Add(SizeOf(S).ToString); // 4
 memo1.Lines.Add(Length(S).ToString); // 8
end;

Bu olayı anlamadım, S değişkenini bellekte nasıl 4 byte alana sığdırırz ?

Bunun sebebi 8 baytlık verinin orada değil, belleğin başka bir yerinde tutulması. Orada tutulan 4 baytlık veri aslında asıl verinin bulunduğu yerin adresini içeriyor.

Sebebini şu linkten takip edebilirsiniz;

Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.
P.Safa:Yaşlanarak değil, yaşayarak tecrübe kazanılır.Zaman insanları değil,armutları olgunlaştırır
C.Yücel:Toprak gibi olmalısın! Ezildikçe sertleşmelisin!Seni ezenler sana muhtaç kalmalı! Hayatı sende bulmalı
S.Canan:Bildiğini zannettiğin an hiç bir şey öğrenemezsin
Bilgi uçar
WWW
Cevapla
#20
Pardon şimdi kafaya dank etti, değişkenin içeriği değilde, değişken (veri) tipinin kapladığı alan boyutu olarak algılamak gerekiyor.
Sabah daha uyukluyor olmanın etkisi sanırım Smile
Linkleri Görebilmeniz İçin Üye Olmanız Gerekiyor. Üye Olabilmek İçin Lütfen Buraya Tıklayınız.
WWW
Cevapla




Konuyu Okuyanlar: 1 Ziyaretçi