Lazarus

Programming => General => Topic started by: wytwyt02 on January 28, 2020, 08:16:39 am

Title: How C++ union to Pascal?
Post by: wytwyt02 on January 28, 2020, 08:16:39 am
Following C++ union:

Code: C  [Select][+][-]
  1. typedef union tagSTKDATAEx
  2. {
  3.         struct
  4.         {
  5.                 float m_fBuyPrice[3];          
  6.                 float m_fBuyVol[3];                    
  7.                 float m_fSellPrice[3];         
  8.                 float m_fSellVol[3];           
  9.                 DWORD m_dwToken;                       
  10.         };
  11.         float m_fDataEx[13];
  12. };

This union structure seems hard to convert to pascal record using case of.
Title: Re: How C++ union to Pascal?
Post by: Handoko on January 28, 2020, 08:18:09 am
Maybe record with variable part:
https://wiki.freepascal.org/Record#Variable_structure (https://wiki.freepascal.org/Record#Variable_structure)

I'm not familiar with this topic but I think you can learn more from this discussion:
https://forum.lazarus.freepascal.org/index.php/topic,45832.msg324601.html#msg324601 (https://forum.lazarus.freepascal.org/index.php/topic,45832.msg324601.html#msg324601)
Title: Re: How C++ union to Pascal?
Post by: wytwyt02 on January 28, 2020, 08:24:17 am
Maybe record with variable part:
https://wiki.freepascal.org/Record#Variable_structure

I still confused, Is it record nested record?
Title: Re: How C++ union to Pascal?
Post by: JernejL on January 28, 2020, 08:38:20 am
it's a case of in a record, each member is at same address.
It translates same as record + case of.
 
Example:
 
Code: Pascal  [Select][+][-]
  1. typedef union
  2.         {
  3.                 void* m_ptr;
  4.                 dLong m_int;
  5.                 dFloat m_float;
  6.         } NewtonMaterialData;
  7.  

This translates to:
 
Code: Pascal  [Select][+][-]
  1. TNewtonMaterialData = packed record
  2. case integer of
  3. 1: (
  4.         m_ptr: Pointer;
  5. );
  6. 2: (
  7.         m_int: int64;
  8. );
  9. 3: (
  10.         m_float: dfloat;
  11. );
  12. end;
  13. PNewtonMaterialData = ^TNewtonMaterialData;
  14.  

the size of c++ union - translated record is size of biggest member.
 
Title: Re: How C++ union to Pascal?
Post by: Handoko on January 28, 2020, 08:45:57 am
@wytwyt02

I usually avoid record with variable part, it seems a bit too hard for me to digest. For simple cases, I usually use absolute.

https://wiki.lazarus.freepascal.org/Absolute
Title: Re: How C++ union to Pascal?
Post by: Thaddy on January 28, 2020, 08:47:19 am
@JernejL
Correct. That is the same as a C union. We call that a variant record in Pascal speak (nothing to do with variants)
https://www.freepascal.org/docs-html/ref/refsu15.html
Title: Re: How C++ union to Pascal?
Post by: PascalDragon on January 28, 2020, 09:30:28 am
This union structure seems hard to convert to pascal record using case of.

That's one of the easy ones (it's more complicated if there are multiple, nested unions):

Code: Pascal  [Select][+][-]
  1. type
  2.   tagSTKDATAEx = record
  3.     case Boolean of
  4.       True: (
  5.         m_fBuyPrice: array[0..2] of Single;
  6.         m_fBuyVol: array[0..2] of Single;
  7.         m_fSellPrice: array[0..2] of Single;
  8.         m_fSellVol: array[0..2] of Single;
  9.         m_dwToken: DWORD
  10.       );
  11.       False: (
  12.         m_fDataEx: array[0..12] of Single;
  13.       );
  14.   end;
  15.  
Title: Re: How C++ union to Pascal?
Post by: JernejL on January 28, 2020, 11:16:02 am
if there are multiple nested unions it is simply best to split them into separate packed records.
Title: Re: How C++ union to Pascal?
Post by: syntonica on January 29, 2020, 03:21:39 pm
Record casting also works quite nicely. Define two equal-sized records with different field structures. I didn't know about "absolute" though. That may be a better solution. I rarely work with unions.
TinyPortal © 2005-2018