Recent

Author Topic: Can this C struct be expressed in FPC Pascal ?  (Read 19535 times)

BrunoK

  • Sr. Member
  • ****
  • Posts: 452
  • Retired programmer
Re: Can this C struct be expressed in FPC Pascal ?
« Reply #90 on: July 12, 2019, 11:16:13 am »
There you have a field with size 0. And now?
This is code extract from my revisited heaptrc unit, specifically representing the structures involved in heap memory allocation :
Code: Pascal  [Select][+][-]
  1.  
  2. type
  3.   RObjclass_pvmt = record         // Must be multiple of 8 bytes, see below.
  4.     _object: TObject;            // The vmt of the allocated TObject descendent
  5. {$IFDEF CPU32}
  6.     locked_incr: longint;        // Global increment of GetMem
  7. {$ENDIF}
  8. {$IFDEF CPU64}
  9.     locked_incr: int64;          // Global increment of GetMem
  10. {$ENDIF}
  11.   end;
  12.   PObjclass_pvmt = ^RObjclass_pvmt;
  13.  
  14.   pheap_mem_info = ^theap_mem_info;
  15.  
  16.   pheap_extra_info = ^theap_extra_info;
  17.   theap_extra_info = record
  18.     exact_info_size: dword;  // exact_info_size as calculated in
  19.     fillproc: tfillextrainfoProc;
  20.     displayproc: tdisplayextrainfoProc;
  21.     sig: TSig;               // used to check if pheap_extra_info^ is still valid
  22. {$IFDEF CPU64}
  23.     sig_al64: dword;         // pad to align data on 16 bytes
  24. {$ENDIF}
  25.     Data: packed Record end; // variable sized array of byte
  26.   end;
  27.  
  28.   ppheap_mem_info = ^pheap_mem_info;
  29.  
  30.   { warning the size of theap_mem_info
  31.     must be a multiple of uintptr so processor that require
  32.     register load alignment on 4/8 bytes wont cause errors. }
  33.  
  34.   { theap_mem_info }
  35.  
  36.   theap_mem_info = packed record
  37.   public
  38.     previous,
  39.     Next: pheap_mem_info;
  40.     todolist: ppheap_mem_info;
  41.     todonext: pheap_mem_info;
  42.     size: ptruint;
  43. {$IFDEF TrackObjectClasses}
  44.     objclass_pvmt: RObjclass_pvmt;
  45. {$ENDIF}
  46.     sig: TSig;          // crc calculated signature
  47. {$ifndef EXTRA and defined(CPU64)}
  48.     sig_al64: dword;    // pad to reach 64
  49. {$ENDIF}
  50.     calls: array [1..tracesize] of codepointer;
  51.     extra_info_size: dword;  // SizeOf(theap_extra_info) +
  52.                              // SizeOftheap_extra_info desired .Data.size
  53.                              // 0 if no extra_info
  54.     VarRec : packed record
  55.       case Boolean of
  56.         False :
  57.           (mem_info : pheap_mem_info; // Back pointer to theap_mem_info record
  58.            data : record end);
  59.         True :
  60.           (extra_info : theap_extra_info);
  61.     end;
  62.     { Copies pre-allocated record to self }
  63.     procedure Initialize;
  64.     { Return the memory size requested to hold both theap_mem_info and Data
  65.         if Self <> nil returns the size that was previously allocated }
  66.     function NewAllocSize(aSize: ptruint): ptruint;
  67.     function calculate_sig : TSig;
  68.     { Retrieve pointer to the mem_info that sits in front of data }
  69.     function GetBackPointerP : pheap_mem_info; { inline; }
  70.     function HasExtraInfo : boolean;
  71.     { Retrieves place to plug deadbeef }
  72.     function TailPointer: PLongWord;
  73.     { Recalculate / adjust the VarRec.mem_info during GetMem and ReallocMem }
  74.     procedure UpdateBackPointer; inline;
  75.   end;
  76.  
Both " data : record end;" are used to do calculations about memory offsets in the variant record. The stuff is messy but using the record methods, the discomfort of working with variant sized records can be aleviated.

Example : calculate invariant part size of heap_mem_info (using empty record).
Code: Pascal  [Select][+][-]
  1.   heap_mem_info_inv_size := pointer(@aheap_mem_info.VarRec.data) - pointer(@aheap_mem_info);
  2.  
The getmem for the structure depends on its different parts.

 

TinyPortal © 2005-2018