Reputation: 55
I am converting the C library to Delphi. I have a problem converting the code below. This is the structure used for communications, so the order must be correct.
Delphi
Tparam_union_params_t = packed record
case Integer of
0: (param_float:single);
1: (param_int32:Int32);
2: (param_uint32:UInt32);
...
...
end;
Tparam_union_t = packed record
param:Tparam_union_params_t // This method requires var name.
type:UInt8;
end;
C Lang
#ifdef __GNUC__
#define PACKED( __Declaration__ ) __Declaration__ __attribute__((packed))
#else
#define PACKED( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop) )
#endif
PACKED(
typedef struct param_union {
union {
float param_float;
int32_t param_int32;
uint32_t param_uint32;
int16_t param_int16;
uint16_t param_uint16;
int8_t param_int8;
uint8_t param_uint8;
uint8_t bytes[4];
}; // This no-named union. no-named is important.
uint8_t type;
}) param_union_t;
My method requires var name but original c code is no-named. How do I convert anonymous union or structure in C to Delphi?
Upvotes: 3
Views: 357
Reputation: 28836
What you have is not bad, but in my article Pitfalls of converting I describe a slightly nicer technique to handle such a union without a name:
param_union_p = ^param_union_t;
param_union_t = packed record
case Integer of
0: (param_float: Single);
1: (param_int32: Int32);
2: (param_uint32: UInt32; // add the members after the union to the largest branch.
&type: UInt8);
3: (param_int16: Int16);
...
...
end;
PParamUnion = ^TParamUnion;
TParamUnion = param_union_t;
Instead of in the UInt32
branch it could also be added to the Single
or Int32
branch of the same size. That would still result in the same memory layout as the struct in C, with &type
at offset 4, and the size of the record being 5, and that is all that counts. Just take a look at the diagram in the article for clarification:
This way, there is no need to give the union part its own type and its own name. If you don't trust the "trick", use the code I give in the same article to check the offsets in C and in Delphi.
Borland and Embarcadero, and also Delphi-JEDI, use(d) the same trick to translate anonymous unions, and the Delphi TVarRec
(for array of const
parameters) and TVarType
(for Variants) records are built that way too.
Upvotes: 6