Konuyu Paylaş : facebook gplus twitter

Konuyu Oyla:
  • Derecelendirme: 0/5 - 0 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Field Alignment, #pragma pack
#1
Bu aralar C/C++ dll wrapper çevrimleri ile çok uğraşır oldum. Karşıma da başlıktaki gibi  "#pragma pack" çıktı. Data hizalama olduğunu öğrendim. "record,array" ler "packed" ifadesi ile kullanılması gerekiyor diye öğrendim. Hepsini uyguladım ama istediğim sonuca ulaşamadım. Bu konuda bilgisi olan var mı?

Örnek C struct
#pragma pack(push, 1)
struct item_details {
   char description[24];
   double qty;
   double price;
   int section;
   int plu;
   double discount;
   double surcharge;
};

struct credit_item_details {
   char description[24];
   int type;
   int operator_id;
   double amount;
};

typedef struct {
   int date;
   int time;
   int timestamp;
   int receipt_no;
   int z_no;
   double total_vat;
   double net_total;
   double payment_cash;
   double payment_ccard;
   double payment_credit;
   double payment_currency;
   int item_count;
   struct item_details items[MAX_PRODUCT_DETAILS];
   int credit_item_count;
   struct credit_item_details credit_items[MAX_PRODUCT_DETAILS];
} sale_receipt_details;
#pragma pack(pop)

Delphi çevrimi
  
{$A-}
{$ALIGN OFF}

TReceiptItemDetails = packed record
   description : packed array[0..23] of AnsiChar;
   qty         : Double;
   price       : Double;
   section     : Integer;
   plu         : Integer;
   discount    : Double;
   surcharge   : Double;
   vatRate     : Double;
   item_unit   : Integer;
   barcode     : packed array[0..15] of AnsiChar;
 end;

 TCreditItemDetails = packed record
   description : packed array[0..23] of AnsiChar;
   credit_type : Integer;
   operator_id : Integer;
   amount      : Double;
 end;
 
 TSaleReceiptDetails = packed record
   rec_date          : Integer;
   rec_time          : Integer;
   timestamp         : Integer;
   receipt_no        : Integer;
   z_no              : Integer;
   total_vat         : Double;
   net_total         : Double;
   payment_cash      : Double;
   payment_ccard     : Double;
   payment_credit    : Double;
   payment_currency  : Double;
   item_count        : Integer;
   items             : packed array[0..MAX_PRODUCT_DETAILS-1] of TReceiptItemDetails;
   credit_item_count : Integer;
   credit_items      : packed array[0..MAX_PRODUCT_DETAILS-1] of TCreditItemDetails;
 end;
Cevapla
#2
(22-12-2017, Saat: 11:38)erkankurtaga Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye OlBu aralar C/C++ dll wrapper çevrimleri ile çok uğraşır oldum. Karşıma da başlıktaki gibi  "#pragma pack" çıktı. Data hizalama olduğunu öğrendim. "record,array" ler "packed" ifadesi ile kullanılması gerekiyor diye öğrendim. Hepsini uyguladım ama istediğim sonuca ulaşamadım. Bu konuda bilgisi olan var mı?

Örnek C struct
#pragma pack(push, 1)
struct item_details {
   char description[24];
   double qty;
   double price;
   int section;
   int plu;
   double discount;
   double surcharge;
};

struct credit_item_details {
   char description[24];
   int type;
   int operator_id;
   double amount;
};

typedef struct {
   int date;
   int time;
   int timestamp;
   int receipt_no;
   int z_no;
   double total_vat;
   double net_total;
   double payment_cash;
   double payment_ccard;
   double payment_credit;
   double payment_currency;
   int item_count;
   struct item_details items[MAX_PRODUCT_DETAILS];
   int credit_item_count;
   struct credit_item_details credit_items[MAX_PRODUCT_DETAILS];
} sale_receipt_details;
#pragma pack(pop)

Delphi çevrimi
  {$A-}

{$ALIGN OFF}


TReceiptItemDetails = packed record
    description : packed array[0..23] of AnsiChar;
   qty         : Double;
   price       : Double;
   section     : Integer;
   plu         : Integer;
   discount    : Double;
   surcharge   : Double;
   vatRate     : Double;
   item_unit   : Integer;
   barcode     : packed array[0..15] of AnsiChar;
 end;

 TCreditItemDetails = packed record
   description : packed array[0..23] of AnsiChar;
   credit_type : Integer;
   operator_id : Integer;
   amount      : Double;
 end;
 
 TSaleReceiptDetails = packed record
   rec_date          : Integer;
   rec_time          : Integer;
   timestamp         : Integer;
   receipt_no        : Integer;
   z_no              : Integer;
   total_vat         : Double;
   net_total         : Double;
   payment_cash      : Double;
   payment_ccard     : Double;
   payment_credit    : Double;
   payment_currency  : Double;
   item_count        : Integer;
   items             : packed array[0..MAX_PRODUCT_DETAILS-1] of TReceiptItemDetails;
   credit_item_count : Integer;
   credit_items      : packed array[0..MAX_PRODUCT_DETAILS-1] of TCreditItemDetails;
 end;

İstediğiniz sonuç nedir ?

Öncelikle C/C++ tarafında ve Delphi tarafında ilgili record/struct'ların size'larını bir kontrol edin. Eşit olmaları gerekir.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#3
(22-12-2017, Saat: 11:42)Tuğrul HELVACI Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol
(22-12-2017, Saat: 11:38)erkankurtaga Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye OlBu aralar C/C++ dll wrapper çevrimleri ile çok uğraşır oldum. Karşıma da başlıktaki gibi  "#pragma pack" çıktı. Data hizalama olduğunu öğrendim. "record,array" ler "packed" ifadesi ile kullanılması gerekiyor diye öğrendim. Hepsini uyguladım ama istediğim sonuca ulaşamadım. Bu konuda bilgisi olan var mı?

Örnek C struct
#pragma pack(push, 1)
struct item_details {
   char description[24];
   double qty;
   double price;
   int section;
   int plu;
   double discount;
   double surcharge;
};

struct credit_item_details {
   char description[24];
   int type;
   int operator_id;
   double amount;
};

typedef struct {
   int date;
   int time;
   int timestamp;
   int receipt_no;
   int z_no;
   double total_vat;
   double net_total;
   double payment_cash;
   double payment_ccard;
   double payment_credit;
   double payment_currency;
   int item_count;
   struct item_details items[MAX_PRODUCT_DETAILS];
   int credit_item_count;
   struct credit_item_details credit_items[MAX_PRODUCT_DETAILS];
} sale_receipt_details;
#pragma pack(pop)

Delphi çevrimi
  {$A-}

{$ALIGN OFF}


TReceiptItemDetails = packed record
    description : packed array[0..23] of AnsiChar;
   qty         : Double;
   price       : Double;
   section     : Integer;
   plu         : Integer;
   discount    : Double;
   surcharge   : Double;
   vatRate     : Double;
   item_unit   : Integer;
   barcode     : packed array[0..15] of AnsiChar;
 end;

 TCreditItemDetails = packed record
   description : packed array[0..23] of AnsiChar;
   credit_type : Integer;
   operator_id : Integer;
   amount      : Double;
 end;
 
 TSaleReceiptDetails = packed record
   rec_date          : Integer;
   rec_time          : Integer;
   timestamp         : Integer;
   receipt_no        : Integer;
   z_no              : Integer;
   total_vat         : Double;
   net_total         : Double;
   payment_cash      : Double;
   payment_ccard     : Double;
   payment_credit    : Double;
   payment_currency  : Double;
   item_count        : Integer;
   items             : packed array[0..MAX_PRODUCT_DETAILS-1] of TReceiptItemDetails;
   credit_item_count : Integer;
   credit_items      : packed array[0..MAX_PRODUCT_DETAILS-1] of TCreditItemDetails;
 end;

İstediğiniz sonuç nedir ?

Öncelikle C/C++ tarafında ve Delphi tarafında ilgili record/struct'ların size'larını bir kontrol edin. Eşit olmaları gerekir.

Yukarıda yaptığım çevrim sizce doğru mu Hocam?
Cevapla
#4
Ayrıntıya girmek için tekrar yazdım yorumu.
{$A-}
{$ALIGN OFF}
ifadelerinden birini kullanmanız yeterli.Bu bildirimi yazdığınız zaman packed ifadelerini kullanmanıza gerek yok zaten aynı işi yapar.Ayrıca en altta {$ALIGN ON} ifadesini koymalısınız.
Bizi Toprağa Gömdüler Fakat Tohum Olduğumuzu Bilmiyorlardı.
Cevapla
#5
(22-12-2017, Saat: 14:34)savasabd Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye OlAyrıntıya girmek için tekrar yazdım yorumu.
{$A-}
{$ALIGN OFF}
ifadelerinden birini kullanmanız yeterli.Bu bildirimi yazdığınız zaman packed ifadelerini kullanmanıza gerek yok zaten aynı işi yapar.Ayrıca en altta {$ALIGN ON} ifadesini koymalısınız.

Peki "packed" ifadesi kullanırsak ne yapmamız gerekiyor?
Cevapla
#6
(22-12-2017, Saat: 16:21)erkankurtaga Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol
(22-12-2017, Saat: 14:34)savasabd Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye OlAyrıntıya girmek için tekrar yazdım yorumu.
{$A-}
{$ALIGN OFF}
ifadelerinden birini kullanmanız yeterli.Bu bildirimi yazdığınız zaman packed ifadelerini kullanmanıza gerek yok zaten aynı işi yapar.Ayrıca en altta {$ALIGN ON} ifadesini koymalısınız.

Peki "packed" ifadesi kullanırsak ne yapmamız gerekiyor?

Hocam varsayılan olarak {$ALIGN ON} hizalama aktiftir.Çünkü hizalama programın hızlı çalışmasını sağlar ama bellekten yer.Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol bir alıntıyla göstereyim.
Example code : Packing a record to reduce storage



type
 // Use the default setting  :   $Align+
 // Declare an unpacked, aligned record
 TAlignedRecord = Record
   name1   : string[4];
   floater : single;
   name2   : char;
   int     : Integer;
 end;

 // Declare a packed record
 TPackedRecord = Packed Record
   name1   : string[4];
   floater : single;
   name2   : char;
   int     : Integer;
 end;

 // Set alignment off
 {$align Off}

 // Declare an unpacked record
 // This will get treated as if packed was on
 TUnPackedRecord = Record
   name1   : string[4];
   floater : single;
   name2   : char;
   int     : Integer;
 end;

var
 alignedRec  : TAlignedRecord;
 packedRec   : TPackedRecord;
 unPackedRec : TUnPackedRecord;

begin
 ShowMessage('Aligned record size = '+IntToStr(SizeOf(alignedRec)));
 ShowMessage('Packed record size = '+IntToStr(SizeOf(packedRec)));
 ShowMessage('UnPacked record size = '+IntToStr(SizeOf(unPackedRec)));
end;
Show full unit code
  Aligned record size = 20
  Packed record size = 14
UnPacked record size = 14

Yani   {$align Off} ile hizalamayı kapttığınız için packed ifadesine ihtiyacınız yok.Packed ifadesi hizalama açıkken kullanılır.Kapalıyken boşuna kullanmış olursunuz çünkü hizalama zaten kapalı.
Bizi Toprağa Gömdüler Fakat Tohum Olduğumuzu Bilmiyorlardı.
Cevapla
#7
(22-12-2017, Saat: 17:05)savasabd Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol
(22-12-2017, Saat: 16:21)erkankurtaga Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye OlPeki "packed" ifadesi kullanırsak ne yapmamız gerekiyor?

Hocam varsayılan olarak {$ALIGN ON} hizalama aktiftir.Çünkü hizalama programın hızlı çalışmasını sağlar ama bellekten yer.Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol bir alıntıyla göstereyim.
Example code : Packing a record to reduce storage



type
 // Use the default setting  :   $Align+
 // Declare an unpacked, aligned record
 TAlignedRecord = Record
   name1   : string[4];
   floater : single;
   name2   : char;
   int     : Integer;
 end;

 // Declare a packed record
 TPackedRecord = Packed Record
   name1   : string[4];
   floater : single;
   name2   : char;
   int     : Integer;
 end;

 // Set alignment off
 {$align Off}

 // Declare an unpacked record
 // This will get treated as if packed was on
 TUnPackedRecord = Record
   name1   : string[4];
   floater : single;
   name2   : char;
   int     : Integer;
 end;

var
 alignedRec  : TAlignedRecord;
 packedRec   : TPackedRecord;
 unPackedRec : TUnPackedRecord;

begin
 ShowMessage('Aligned record size = '+IntToStr(SizeOf(alignedRec)));
 ShowMessage('Packed record size = '+IntToStr(SizeOf(packedRec)));
 ShowMessage('UnPacked record size = '+IntToStr(SizeOf(unPackedRec)));
end;
Show full unit code
  Aligned record size = 20
  Packed record size = 14
UnPacked record size = 14

Yani   {$align Off} ile hizalamayı kapttığınız için packed ifadesine ihtiyacınız yok.Packed ifadesi hizalama açıkken kullanılır.Kapalıyken boşuna kullanmış olursunuz çünkü hizalama zaten kapalı.
Haklısınız bu kodu gördüm ve uyguladım. Ama sonuç değişmedi istediğim sonucu alamıyorum. Sürekli başa dönüyorum.
Cevapla
#8
#pragma pack(pop)  yerine denk gelen   {$align on} ifadesini koydunuz mu?
Bizi Toprağa Gömdüler Fakat Tohum Olduğumuzu Bilmiyorlardı.
Cevapla
#9
(22-12-2017, Saat: 17:22)savasabd Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol#pragma pack(pop)  yerine denk gelen   {$align on} ifadesini koydunuz mu?

Her şeyi denedim. {$A1} ilgili record {$ALIGN ON}  denedim olmadı. Record ve array lerin hepsini packed ifadesini kullandım. Sonuç değişmedi. İşin içinden çıkamadım. "#pragma pack(1)"  "#pragma pack(pop)" direktifleri arasındaki recordları birbiri içinde de hizalamak gerekiyor mu? Örnek Olarak

#pragma pack(push, 1)
struct item_details {
   char description[24];
   double qty;
   double price;
   int section;
   int plu;
   double discount;
   double surcharge;
};

struct credit_item_details {
   char description[24];
   int type;
   int operator_id;
   double amount;
};
#pragma pack(pop)

Delphi çevrimi 

  
{$A1}
TReceiptItemDetails = record
    description : array[0..23] of AnsiChar;//0-23
   qty         : Double;                  //24-31
   price       : Double;                  //32-39
   section     : Integer;                 //40-43
   plu         : Integer;                 //44-47
   discount    : Double;                  //48-55
   surcharge   : Double;                  //56-63
   vatRate     : Double;                  //64-71
   item_unit   : Integer;                 //72-75
   barcode     : packed array[76..91] of AnsiChar;//76-91
 end;

 TCreditItemDetails = record
   description : array[0..23] of AnsiChar; //92-115
   credit_type : Integer;
   operator_id : Integer;
   amount      : Double;
 end;
{$ALIGN ON}

gibi bir çevrim doğru mu?
Cevapla
#10
Hocam en baştaki kodda şu üç kısım fazla
   vatRate     : Double;
   item_unit   : Integer;
   barcode     :  array[0..15] of byte;
Bunları kaldırınca size'ları aynı,onları kaldırırsanız bir sıkıntı yok orada.Aşağıda da onlar fazla yine.Ayrıca packed ifadesini hala kullanmışsınız,gerek yok ona.
Bizi Toprağa Gömdüler Fakat Tohum Olduğumuzu Bilmiyorlardı.
Cevapla

Konuyu Paylaş : facebook gplus twitter



Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  [Çözüldü]Çözemediğim veri tabanı hatası (Cannot access field as type Text) musdi42 15 1.141 19-01-2017, Saat: 14:07
Son Yorum: yhackup



Konuyu Okuyanlar: 1 Ziyaretçi