PSafeArray tipli değişkenimi Array of Objects tipli değişkene nasıl nasıl atabilirim.

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
Kullanıcı avatarı
NewMember
Üye
Mesajlar: 990
Kayıt: 29 Haz 2005 06:57
Konum: Bursa

PSafeArray tipli değişkenimi Array of Objects tipli değişkene nasıl nasıl atabilirim.

Mesaj gönderen NewMember »

Arkadaşlar merhaba;
Aşağıdaki gibi bir objectim var.

Kod: Tümünü seç

unit MyResponseModel;

interface


type
  TMyResponse = class
  private
    FStatus: integer;
    FSorguNo: string;
    FStatusMessage: string;
    { private declarations }
  protected
    { protected declarations }
  public
    { public declarations }
    property Status: Integer read FStatus write
      FStatus;
    property SorguNo: string read FSorguNo write
      FSorguNo;
    property  StatusMessage: string read FStatusMessage write
      FStatusMessage;

    constructor Create();
    destructor Destroy(); override;
  published
    { published declarations }
  end;

implementation

{ TRequest }

constructor TMyResponse.Create();
begin
     inherited Create;
end;

destructor TMyResponse.Destroy;
begin
  inherited Destroy;
end;

end.

Örnek olarak şöyle de bir array object içeren JSON dosyam var.

Kod: Tümünü seç


[
  {
    "Status": 0,
    "StatusMessage": "Status Message 0",
    "SorguNo": "Sorgu No 0"
  },
  {
    "Status": 1,
    "StatusMessage": "Status Message 1",
    "SorguNo": "Sorgu No 1"
  },
  {
    "Status": 2,
    "StatusMessage": "Status Message 2",
    "SorguNo": "Sorgu No 2"
  }
]


C# ta NewtonSoft kutuphanesini kullanarak yazdığım Json dosyalarını deserailize eden bir dllim var.
Bu dll de kullandığım methodum aşağıda.

Kod: Tümünü seç

 public MyResponse[] DeSerializeFromJsonFileToObjectArray(string fileName)
        { 
            string jsonString = File.ReadAllText(fileName);
            try
            {
                var model = JsonConvert.DeserializeObject<MyResponse[]>(jsonString);
                return model;
            }
            catch (Exception)
            {
                throw;
            } 
        } 
        
        
Bu dll i delphide TypeLibrary olarak import ettim.

Doğal olarak typeLibraryde bu metod aşağıdaki şekle dönüştü.

Kod: Tümünü seç

function TIndemSoftJsonHelper.DeSerializeFromJsonFileToObjectArray(const fileName: WideString): PSafeArray;
begin
  Result := DefaultInterface.DeSerializeFromJsonFileToObjectArray(fileName);
end;
Dllin içinde MyResponse classımda var.Bu classıda _MyResponse adında tlb dosyasına alıyor.

Doğal olarak tam tip olarak dönüş vermiyro.Bu konuya yeni girdim.İmport ederken methoddan geriye array of _MyResponse tipinde birşeyler döneceğini beklemiştim. :lol:
Ancak şimdi anlıyorum ki PSafeArray olarak dönmesi son derece normal.

Ben tlb dosyasındaki metodumu çağırıyorum aşağıdaki gibi

Kod: Tümünü seç

var
  myArray: PSafeArray;
 responsearray: array of _MyResponse; 
begin
  myArray := MyDll.DeSerializeFromJsonFileToObjectArray('C:\Users\Asus\Desktop\Temp\deneme.json');
 //Yukarıda örnek olarak verdiğim josn dosyası
 
İşte burda takılıp kalıyorum.
Fonksiyon bana PsafeArray tipinde donus verdi.myarray isimli değişkenime aldım.
Ama şimdi bunları okumma lazım ve bunun içinde propertyleri bilinen _MyResponse veya MyResponse tipinde bir değişkene cast etmeliyim.
Ama nasıl?
Çok araştırdım ama bulamadım.
Bilgisi olan arkadaşlar yardımcı olursa çok makbule geçecek.
Şimdiden teşekkürler.....
ertank
Kıdemli Üye
Mesajlar: 1650
Kayıt: 12 Eyl 2015 12:45

Re: PSafeArray tipli değişkenimi Array of Objects tipli değişkene nasıl nasıl atabilirim.

Mesaj gönderen ertank »

Merhaba,

Gereksiz zorlu yollardan gitmişsiniz.

Öncelikle, Netwonsoft kütüphanesini kullanmanıza gerek yok.

Yine eğer zorunlu değil ise "class" kullanmanıza gerek yok.

JSON çok standart bir yapı. Delphi içindeki standart System.JSON ünitesi ile işinizi görebilirsinz. Ancak alternatif Delphi JSON kütüphaneleri işinizi daha da kolaylaştırmaya yardımcı olabilir. Ben genelde mORMot framework içindeki JSON kütüphanelerini tercih ediyorum. Oldukça performanslı çalışıyorlar.
https://github.com/synopse/mORMot

Aşağıdaki gibi mORMot kullanarak yapmak istediğiniz işlemi gerçekleştirebilirsiniz.

Kod: Tümünü seç

type
  TStatus = packed record
    Status: Integer;
    StatusMessage: string;
    SorguNo: string;
  end;
  TStatuses = TArray<TStatus>;


....
uses
  SynCommons;

var
  Statuler: TStatuses;
  Json: string;
begin
  SetLength(Statuler, 1);
  Statuler[0].Status := 1;
  Statuler[0].StatusMessage := 'test mesajı';
  Statuler[0].SorguNo := 'no 1';

  // Serialize örneği
  Json := string(SynCommons.DynArraySaveJSON(Statuler, TypeInfo(TStatuses)));
  if Json.IsEmpty then
  begin
    ShowMessage('Json oluşturulamadı');
    Exit();
  end;

  Memo1.Lines.Add(Json);
end;
Delphi 10.3.3 ile çalışan hem json array oluşturma, hem json array metni üzerinden record bilgisini dolduran örnek uygulamayı ekte bulabilirsiniz.

Uygulamayı derleyip çalıştırabilmek için yukarıdaki bağlantısından kodları alıp test projesi search path veya Delphi library search path içine eklemelisiniz. Tek başına SynCommons.pas dosyası yeterli değildir. Tüm kodları alıp bir dizin içine açarak kullanmanızı tavsiye ederim.

Son olarak, kütüphane array olmayan json ve daha karmaşık json yapılarını da desteklemektedir. Standart (array olmayan) json için aşağıdaki iki fonksiyonu kullanabilirsiniz.

Kod: Tümünü seç

SynCommons.RecordSaveJSON()
SynCommons.RecordLoadJSON()
Umarım bu bilgiler bakış açınızı değiştirebilir.
Dosya ekleri
json array mormot.7z
(53.54 KiB) 73 kere indirildi
Kullanıcı avatarı
NewMember
Üye
Mesajlar: 990
Kayıt: 29 Haz 2005 06:57
Konum: Bursa

Re: PSafeArray tipli değişkenimi Array of Objects tipli değişkene nasıl nasıl atabilirim.

Mesaj gönderen NewMember »

@ertank üstadım.
Çok teşekkürler.Bu yola girmemin sebebi object array vb complex tiplerde sorun yaşamamndandı.uLKJson kutuphanesi ile çalışıyordum.Ama ne yaparsam yapayım array objectleri deserialize ederken Türkçe karakter sorunu dahil başka sorunlarda yaşadım.Ayrıca NewtonSoft kutuphanesinde daha basit bir şekilde bunları yapmamızdan dolayı bu yola girdim.Başka kutuphane araştırmam da oldu ancak sizin soylediğinize denk gelmemiştim.
Hemen deneyip sonucu buraya yazacağım.Ancak yukarıdaki sorunun da çözülmesini çok isterdim.Zira başka bir yerde başka bir işlem için yine gereksinimimiz olacaktır mutlaka.
ertank
Kıdemli Üye
Mesajlar: 1650
Kayıt: 12 Eyl 2015 12:45

Re: PSafeArray tipli değişkenimi Array of Objects tipli değişkene nasıl nasıl atabilirim.

Mesaj gönderen ertank »

Şahsen mORMot ile işleyemediğim tek bir JSON'a denk geldim. O da "recursive" olarak farklı yapılarda, aynı isimde nesneler kullanmıştı. Delphi'de record için "forward decleration" desteği olmadığından mORMot ile çalışmadı.

Bu istisnayı Delphi standart JSON kütüphanesi ile manuel kod yazarak de-serialize etmem gerekti. Bunun dışında bütün JSON işlerimi mORMot ile görebildim. mORMot özünde UTF8 ile işlem yapıyor. Türkçe konusunda da hiç sorun yaşamadım.

Dolayısıyla .NET Netwonsoft JSON kütüphanesine ihtiyacınız olacağını gerçekten düşünmüyorum.
Kullanıcı avatarı
NewMember
Üye
Mesajlar: 990
Kayıt: 29 Haz 2005 06:57
Konum: Bursa

Re: PSafeArray tipli değişkenimi Array of Objects tipli değişkene nasıl nasıl atabilirim.

Mesaj gönderen NewMember »

@ertank ustadım çok teşekkürler.
Üşenmemiş birde deneme projesi yazmışsınız.Minnettarım.
Ancak Delphi 10.2 Tokyo versiyonunu kullanıyorum.Componenti install edemedim.Bu konuda bir önerin varmı?
ertank
Kıdemli Üye
Mesajlar: 1650
Kayıt: 12 Eyl 2015 12:45

Re: PSafeArray tipli değişkenimi Array of Objects tipli değişkene nasıl nasıl atabilirim.

Mesaj gönderen ertank »

"Component install" diye birşey yok. Kod kullanarak yapılacak işlem.
İlgili bağlantıdan framework kodları indirilecek. SynCommons.pas dosyasının olduğu dizin Search Path içine eklenecek.
Kullanıcı avatarı
NewMember
Üye
Mesajlar: 990
Kayıt: 29 Haz 2005 06:57
Konum: Bursa

Re: PSafeArray tipli değişkenimi Array of Objects tipli değişkene nasıl nasıl atabilirim.

Mesaj gönderen NewMember »

Çok ozur dilerim.dosyaların içinde compil.bat gorunce install edileceğini düşündüm.
Çalıştırdım şu an.
Ancak deserialize komutunda serialize edilemiyor.
Orda açıklamada yazmışsınız bu bloğa gelirse TRecord ile json nesnesi arasında uyumsuzluk vardır demişsiniz.
Aslında orda siz TRecord nesnesini ve properytlerini doğru yapılandırmışsınız.Tekrar bend ekontrol ettim.Ama bu blokta takılıyor.
Sizce neden olabilir.

Sizin yazdığınız record:

Kod: Tümünü seç

 TStatus = packed record
    Status: Integer;
    StatusMessage: string;
    SorguNo: string;
  end;
  TStatuses = TArray<TStatus>;
Buda Json:

Kod: Tümünü seç

[{"Status":0,"StatusMessage":"","SorguNo":"ssss"},{"Status":0,"StatusMessage":"","SorguNo":"ssss"},{"Status":0,"StatusMessage":"","SorguNo":"ssss"}]
Birebir uyuyor aslında.


Hatta sizden gelen örneği hiç bir yerini değiştirmeden denedim ondada de serialze de aynı hatayı verdi.
ertank
Kıdemli Üye
Mesajlar: 1650
Kayıt: 12 Eyl 2015 12:45

Re: PSafeArray tipli değişkenimi Array of Objects tipli değişkene nasıl nasıl atabilirim.

Mesaj gönderen ertank »

Benim hatamdan kaynaklı. Çünkü kod içinde yanlışlıkla normal JSON de-serialize örneğini bırakmışım.
60 numaralı satırı aşağıdaki gibi değiştirir iseniz çalışacaktır

Kod: Tümünü seç

  if not SynCommons.DynArrayLoadJSON(Statuler, RawUTF8(Edit1.Text), TypeInfo(TStatuses)) then
Düzeltilmiş proje ektedir.
Dosya ekleri
json array mormot.7z
(53.5 KiB) 87 kere indirildi
Kullanıcı avatarı
NewMember
Üye
Mesajlar: 990
Kayıt: 29 Haz 2005 06:57
Konum: Bursa

Re: PSafeArray tipli değişkenimi Array of Objects tipli değişkene nasıl nasıl atabilirim.

Mesaj gönderen NewMember »

Çok teşekkürler.
Tam bende buldum ve DynArrayLoadJSON metodu ile oluyor yazıcaktım ki siz yazdınız.
Diğer metodlarınıda inceledim bu arada.Hakikaten çok güzel bir kütüphane imiş.
Boşuna taklalar attırmışız.
Çok sağolun ne diyim Allah razı olsun. :bravo: :bravo: :bravo:
Cevapla