0

How does one convert a union struct into a Delphi record?

This is the C++ struct

union {
    struct {
        uint32_t  l_i_reserved1;
    } linux1;
    struct {
        uint32_t  h_i_translator;
    } hurd1;
    struct {
        uint32_t  m_i_reserved1;
    } masix1;
} osd1;             /* OS dependent 1 */

This was my attempt, but i dont think it's right?

osd1 : Record
  case Cardinal of
    0: (l_i_reserved1 : Cardinal);
    1: (h_i_translator : Cardinal);
    2: (m_i_reserved1 : Cardinal);
  end;

I also need to conver this struct into a Record

union {
    struct {
        uint8_t l_i_frag;   /* Fragment number */
        uint8_t l_i_fsize;  /* Fragment size */
        uint16_t    i_pad1;
        uint16_t    l_i_uid_high;   /* these 2 fields    */
        uint16_t    l_i_gid_high;   /* were reserved2[0] */
        uint32_t    l_i_reserved2;
    } linux2;
    struct {
        uint8_t h_i_frag;   /* Fragment number */
        uint8_t h_i_fsize;  /* Fragment size */
        uint16_t    h_i_mode_high;
        uint16_t    h_i_uid_high;
        uint16_t    h_i_gid_high;
        uint16_t    h_i_author;
    } hurd2;
    struct {
        uint8_t m_i_frag;   /* Fragment number */
        uint8_t m_i_fsize;  /* Fragment size */
        uint16_t    m_pad1;
        uint32_t    m_i_reserved2[2];
    } masix2;
} osd2;                 /* OS dependent 2 */

Would the same concept apply?

Thanks

Jake Evans
  • 978
  • 5
  • 13
  • 33
  • Same concept applies. Convert the inline structs to records. Then use variant record as before. – David Heffernan Feb 07 '15 at 19:40
  • How do I have multiple multiple records in one? Your answer only works for one union struct. – Jake Evans Feb 07 '15 at 19:55
  • No. Convert each internal struct to a record. And then make a variant record containing them. Don't try to look for a black box answer, try to understand. You are basically there though. You already translated one union. once you've done one, the rest are all the same. – David Heffernan Feb 07 '15 at 20:00
  • Just FWIW: [for a better understanding](http://www.rvelthuis.de/articles/articles-convert.html#unions). – Rudy Velthuis Feb 08 '15 at 01:38
  • @Rudy that's a good article but you don't account for alignment when you translate a union in the middle of the struct. Adding remaining fields to largest variant part is wrong. – David Heffernan Feb 08 '15 at 06:49
  • If you use unions, you want them to be unaligned anyway, otherwise the variant part might not even work correctly. Note that that "trick" is used in the RTL and Winapi units as well. You *may* have to do a manual align. – Rudy Velthuis Feb 09 '15 at 01:05
  • @rudy You don't understand my point yet. You've made a big mistake. I can help. If you let me. Remember that padding can be after the final member. – David Heffernan Feb 09 '15 at 08:57
  • @Rudy Consider a union with one branch size 2, alignment 2, and the other branch size 3, alignment 1. That union has size 4, alignment 2. There's an extra padding byte. Add bytes onto the end of the size 3 branch and you'll lose that padding byte. I don't care that other people have used this trick. It's wrong. They made the same mistake as you. Alignment is chronically misunderstood by the Delphi community. Emba devs included. – David Heffernan Feb 09 '15 at 13:40
  • If you attach the rest fof the struct to the 3 byte part, you are not doing what I advise in the article. I recommend using the **largest** of the variant parts, to avoid such problems. That will, most of the time, automatically take care of alignment problems too. See the diagram in the article. – Rudy Velthuis Feb 10 '15 at 08:07
  • @Rudy Do you think I am stupid or something? You know I know what I am talking about in this area. Now, as for your latest comment, 3 is larger than 2 isn't it. Your article gets it badly wrong. It's hard to do this in comments to a question. I'm happy to help you fix your article to give sound advice if you'd like me to. Contact me by email or google+ or twitter if you want me to help in a more viable medium. It's easy for me to provide a program that shows you the problem. Perhaps then you'd engage. – David Heffernan Feb 11 '15 at 07:36
  • @RudyVelthuis Try this: http://pastebin.com/V7sjQmVF – David Heffernan Feb 11 '15 at 10:47
  • @David: I know that. The TUnion is 4 bytes in size, so you'll have to add manual alignment before b4. IIRC, I do mention that in the article. – Rudy Velthuis Feb 11 '15 at 18:56
  • @Rudy That's a totally stupid idea!! And utterly needless. And your article doesn't mention this. It just says add in to the longest part and it's all good. That is a good article marred by this one clanger. That you won't admit you got wrong. – David Heffernan Feb 11 '15 at 19:07
  • @Rudy Also, *If you use unions, you want them to be unaligned*. Categorically that is wrong. On some platforms alignment is mandatory. Even when it is not alignment is vitally important for performance. – David Heffernan Feb 11 '15 at 20:40

0 Answers0