Prof A Olowofoyeku (The African Chief) a écrit:
On 19 Dec 2002 at 4:22, Frank Heckenbach wrote:
[...]
AND there is a way to do it in Pascal. Some unions and structures are impossible to convert because there is no way to achieve the conversion in Pascal,
typedef struct _LDT_ENTRY { WORD LimitLow; WORD BaseLow; union { struct { BYTE BaseMid; BYTE Flags1; BYTE Flags2; BYTE BaseHi; } Bytes; struct { DWORD BaseMid:8; DWORD Type:5; DWORD Dpl:2; DWORD Pres:1; DWORD LimitHi:4; DWORD Sys:1; DWORD Reserved_0:1; DWORD Default_Big:1; DWORD Granularity:1; DWORD BaseHi:8; } Bits; } HighWord; } LDT_ENTRY,*PLDT_ENTRY,*LPLDT_ENTRY;
What about the following
---------------------------------------------------------- program teststruc;
{$define DWORD cardinal}
type tBytes = packed record BaseMid: BYTE; Flags1: BYTE; Flags2: BYTE; BaseHi: BYTE end; type tBits = packed record BaseMid: DWORD(8); Typ: DWORD(5); Dpl: DWORD(2); Pres: DWORD(1); LimitHi: DWORD(4); Sys: DWORD(1); Reserved_0: DWORD(1); Default_Big: DWORD(1); Granularity: DWORD(1); BaseHi: DWORD(8) end; type tHighWord = packed record case integer of 1: (Bytes: tBytes); 2: (Bits: tBits) end;
type tLDT_ENTRY = packed record LimitLow: WORD; BaseLow: WORD; HighWord: tHighWord; end;
var LDT_ENTRY: tLDT_ENTRY; PLDT_ENTRY,LPLDT_ENTRY: ^tLDT_ENTRY;
begin with LDT_ENTRY.HighWord do begin with Bytes do begin BaseMid:=$DE; Flags1 :=$AD; Flags2 :=$BE; BaseHi :=$EF; end; with Bits do writeln(BaseMid,' ', Typ,' ', Dpl,' ', Pres,' ', LimitHi,' ', Sys,' ', Reserved_0,' ', Default_Big,' ', Granularity,' ', BaseHi); end; end.
---------------------------------------------------------- it compiles and gives the expected result (on an ix86 low endian machine)
222 13 1 1 14 1 1 0 1 239
Not so easy to implement automatically, however. It needs extra identifiers for type and var of this type: I do not understand enough C to say if HighWord, Bytes and Bits are type names or variable names which can be used to refer to the struct coponent as a whole (I guess the second). Finally Type cannot be an identifier: it is replaced by Typ.
If you don't mind to have identifiers to refer collectively to components, the following (simpler) also works, and is probably enough for C interfacing
------------------------------------------------------------------------- program teststruc;
{$define DWORD cardinal}
type tLDT_ENTRY = packed record LimitLow: WORD; BaseLow: WORD; case (Bytes,Bits) of Bytes: (BaseMid: BYTE; Flags1: BYTE; Flags2: BYTE; BaseHi: BYTE); Bits: (BaseMid2: DWORD(8); Typ: DWORD(5); Dpl: DWORD(2); Pres: DWORD(1); LimitHi: DWORD(4); Sys: DWORD(1); Reserved_0: DWORD(1); Default_Big: DWORD(1); Granularity: DWORD(1); BaseHi2: DWORD(8)); end; var LDT_ENTRY: tLDT_ENTRY; PLDT_ENTRY,LPLDT_ENTRY: ^tLDT_ENTRY;
begin with LDT_ENTRY do begin BaseMid:=$DE; Flags1 :=$AD; Flags2 :=$BE; BaseHi :=$EF; writeln(BaseMid2,' ', Typ,' ', Dpl,' ', Pres,' ', LimitHi,' ', Sys,' ', Reserved_0,' ', Default_Big,' ', Granularity,' ', BaseHi2) end; readln end.
-----------------------------------------------------------------------
But I had to give a different name to BaseMid and BaseHi in the two case parts
Maurice