vladh
asked on
C to Pascal(Delphi) translation
Ladies and Gentlemen,
There are a few packages out there that claim the ability to translate C headers for use with Pascal/Delphi. I don't really have the time to download/try them all. Does anyone have a good experience using a particular package that they can recommend? Shareware/freeware is preferrable, of course.
Meanwhile, if anyone can assist with translation of this C declaration into Delphi, I would greatly appreciate it:
-------------------------- ---
typedef union
switch (DmiDataType_t type) value {
case MIF_COUNTER: DmiCounter_t counter;
case MIF_COUNTER64: DmiCounter64_t counter64;
case MIF_DISPLAYSTRING: DmiString_t* displaystring;
} DataUnion_t;
-------------------------- ----
Thank you for your time and help
Vladimir
There are a few packages out there that claim the ability to translate C headers for use with Pascal/Delphi. I don't really have the time to download/try them all. Does anyone have a good experience using a particular package that they can recommend? Shareware/freeware is preferrable, of course.
Meanwhile, if anyone can assist with translation of this C declaration into Delphi, I would greatly appreciate it:
--------------------------
typedef union
switch (DmiDataType_t type) value {
case MIF_COUNTER: DmiCounter_t counter;
case MIF_COUNTER64: DmiCounter64_t counter64;
case MIF_DISPLAYSTRING: DmiString_t* displaystring;
} DataUnion_t;
--------------------------
Thank you for your time and help
Vladimir
ASKER
TOndrej,
Thanks for quick reply... How do I actually use this record and how do I pass the value to be checked in the CASE statement? Can you please show an example...
Thanks
Vladimir
Thanks for quick reply... How do I actually use this record and how do I pass the value to be checked in the CASE statement? Can you please show an example...
Thanks
Vladimir
The CASE stadment has no value meanning. It is used like "union" in C.
TOndrej: you have a mistake -- you forget "DmiDataType_t type".
Here is the fixed version:
type
DataUnion_t = (packed) record
case value: DmiDataType_t of
0: ( mif_counter: DmiCounter_t; );
1: ( mif_counter64: DmiCounter64_t; );
2: ( mif_displaystring: PDmiString_t; );
end;
Why packed record... ?
TOndrej: you have a mistake -- you forget "DmiDataType_t type".
Here is the fixed version:
type
DataUnion_t = (packed) record
case value: DmiDataType_t of
0: ( mif_counter: DmiCounter_t; );
1: ( mif_counter64: DmiCounter64_t; );
2: ( mif_displaystring: PDmiString_t; );
end;
Why packed record... ?
ASKER
Ok then,
and the DmiDataType_t is declared as
---------------------
typedef enum {
MIF_DATATYPE,
MIF_COUNTER,
MIF_GAUGE,
....
MIF_DATE
} DmiDataType_t
-------------------------- -
What should this look like in a Delphi declaration?
Thanks
Vlad
and the DmiDataType_t is declared as
---------------------
typedef enum {
MIF_DATATYPE,
MIF_COUNTER,
MIF_GAUGE,
....
MIF_DATE
} DmiDataType_t
--------------------------
What should this look like in a Delphi declaration?
Thanks
Vlad
> TOndrej: you have a mistake -- you forget "DmiDataType_t type".
I don't think so, it's just a union switch identifier. You can for example take a look like TWMMouse is declared in Messages unit.
TWMMouse = packed record
Msg: Cardinal;
Keys: Longint;
case Integer of
0: (
XPos: Smallint;
YPos: Smallint);
1: (
Pos: TSmallPoint;
Result: Longint);
end;
this means that if you have var Message: TWMMouse;
you can use it either as if it was either
TWMMouse = packed record
Msg: cardinal;
Keys: Longint;
XPos: Smallint;
YPos: Smallint;
end;
or
TWMMouse = packed record
Msg: Cardinal;
Keys: Longint;
Pos: TSmallPoint;
Result: Longint);
end;
- that's what union means - you can represent the same memory location differently.
> What should this look like in a Delphi declaration?
That would be (in nice Delphi form ;-)
type
TDmiDataType = (dmiDataType, dmiCounter, dmiGauge, ..., dmiDate);
Hope this helps
I don't think so, it's just a union switch identifier. You can for example take a look like TWMMouse is declared in Messages unit.
TWMMouse = packed record
Msg: Cardinal;
Keys: Longint;
case Integer of
0: (
XPos: Smallint;
YPos: Smallint);
1: (
Pos: TSmallPoint;
Result: Longint);
end;
this means that if you have var Message: TWMMouse;
you can use it either as if it was either
TWMMouse = packed record
Msg: cardinal;
Keys: Longint;
XPos: Smallint;
YPos: Smallint;
end;
or
TWMMouse = packed record
Msg: Cardinal;
Keys: Longint;
Pos: TSmallPoint;
Result: Longint);
end;
- that's what union means - you can represent the same memory location differently.
> What should this look like in a Delphi declaration?
That would be (in nice Delphi form ;-)
type
TDmiDataType = (dmiDataType, dmiCounter, dmiGauge, ..., dmiDate);
Hope this helps
>> I don't think so, it's just a union switch identifier.
A union switch identifier can be a type (like in TWMMouse) or a variable with a type (like in the question "(DmiDataType_t type) value").
vladh: Please correct me if i'm wrong, but I think that your structure "DataUnion_t" contains a variable "value" of the type "(DmiDataType_t type)".
A union switch identifier can be a type (like in TWMMouse) or a variable with a type (like in the question "(DmiDataType_t type) value").
vladh: Please correct me if i'm wrong, but I think that your structure "DataUnion_t" contains a variable "value" of the type "(DmiDataType_t type)".
ASKER
romi_k,
Yes, I believe there is a "value" variable that seems to have the purpose of actually passing the required type to the record. Could anyone show an example as to how this type of data structure would actually be used in a program?
Thank you
Yes, I believe there is a "value" variable that seems to have the purpose of actually passing the required type to the record. Could anyone show an example as to how this type of data structure would actually be used in a program?
Thank you
I guess you're right, I've made a mistake. Should be
type
TDmiDataType = (dmiDataType, dmiCounter, dmiGauge, ..., dmiDate);
TDataUnion = (packed) record // try with or without packed - typically it should be packed but depends on the C compiler switch
DataType: TDmiDataType;
case Integer of
0: (
counter: TDmiCounter;
);
1: (
counter64: TDmiCounter64;
);
2: (
displaystring: PDmiString;
);
end;
and then you would use it as:
var
MyUnion: TDataUnion;
C: TDmiCounter;
C64: TDmiCounter64;
S: PDmiString;
....
case MyUnion.DataType of
dmiCounter:
C := MyUnion.counter;
dmiCounter64:
C64 := MyUnion.counter64;
....
dmiDisplayString:
S := MyUnion.displaystring;
end;
Hope this helps
type
TDmiDataType = (dmiDataType, dmiCounter, dmiGauge, ..., dmiDate);
TDataUnion = (packed) record // try with or without packed - typically it should be packed but depends on the C compiler switch
DataType: TDmiDataType;
case Integer of
0: (
counter: TDmiCounter;
);
1: (
counter64: TDmiCounter64;
);
2: (
displaystring: PDmiString;
);
end;
and then you would use it as:
var
MyUnion: TDataUnion;
C: TDmiCounter;
C64: TDmiCounter64;
S: PDmiString;
....
case MyUnion.DataType of
dmiCounter:
C := MyUnion.counter;
dmiCounter64:
C64 := MyUnion.counter64;
....
dmiDisplayString:
S := MyUnion.displaystring;
end;
Hope this helps
There is a nice document on ftp://delphi-jedi.org/manuals/Tutorial4.zip explaining the conversion rules (unions are there too, also the packed directive)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
P.S.:
1. This is the exact translation (except for "MIF_" and capital letters...)
2. This way it is easy to understand that "value" controls the type (Note that in reality it doesn't)
RK
1. This is the exact translation (except for "MIF_" and capital letters...)
2. This way it is easy to understand that "value" controls the type (Note that in reality it doesn't)
RK
Have a look at http://delphi-jedi.org and consider joining us if you are interested in converting from C to Delphi.
Hi, romi_k,
> TDataUnion = record
> case value: TDmiDataType of
> 0: ( counter: TDmiCounter; );
> 1: ( counter64: TDmiCounter64; );
> 2: ( displaystring: PDmiString; );
> end;
> This is what needs to be there!!!
IMHO, there's not much difference between that and my later comment:
TDataUnion = (packed) record
DataType: TDmiDataType;
case Integer of
0: ( counter: TDmiCounter; );
1: ( counter64: TDmiCounter64; );
2: ( displaystring: PDmiString; );
end;
is there? I will be thankful for your explanation. Cheers
> TDataUnion = record
> case value: TDmiDataType of
> 0: ( counter: TDmiCounter; );
> 1: ( counter64: TDmiCounter64; );
> 2: ( displaystring: PDmiString; );
> end;
> This is what needs to be there!!!
IMHO, there's not much difference between that and my later comment:
TDataUnion = (packed) record
DataType: TDmiDataType;
case Integer of
0: ( counter: TDmiCounter; );
1: ( counter64: TDmiCounter64; );
2: ( displaystring: PDmiString; );
end;
is there? I will be thankful for your explanation. Cheers
No difference in action. But wer'e talking about translating code, and why I wrote is the exact translation from what was given.
RK.
RK.
Hi romi_k,
I think that your version is better and more readable. I'm going to use it from now on.
I have translated unions before but never with a switch based on value...
Also I've never seen this type of record in Delphi before.
Thank you for your help.
I think that your version is better and more readable. I'm going to use it from now on.
I have translated unions before but never with a switch based on value...
Also I've never seen this type of record in Delphi before.
Thank you for your help.
I haevn't seen this kind of switch in C before...
So now will you accpet the answer or do you still want to find a program that translates from C to Delphi ?
RK.
So now will you accpet the answer or do you still want to find a program that translates from C to Delphi ?
RK.
ASKER
Gentlemen,
It looks like I must use the switch as an integer value and won't be able to actually use a dataset type as in
type
TDmiDataType = (dmiDataType, dmiCounter, dmiGauge, ..., dmiDate);
i.e. I won't be able to do comparison such as
case value of
dmiCounter : ....
Compiler complains that the identifier is re-declared. Oh well, this is good enough, not as slick as I would want it, but workable.
Yes I still do need a program to do the header conversion for the future as I am sure I'll have same situations in the future.
However, I feel that for the purpose of this discussion each of you deserves the points - you both put enough time in answering my question.
Thank you both. TOnrej, I created another question for you with the points.
Cheers
Vlad
It looks like I must use the switch as an integer value and won't be able to actually use a dataset type as in
type
TDmiDataType = (dmiDataType, dmiCounter, dmiGauge, ..., dmiDate);
i.e. I won't be able to do comparison such as
case value of
dmiCounter : ....
Compiler complains that the identifier is re-declared. Oh well, this is good enough, not as slick as I would want it, but workable.
Yes I still do need a program to do the header conversion for the future as I am sure I'll have same situations in the future.
However, I feel that for the purpose of this discussion each of you deserves the points - you both put enough time in answering my question.
Thank you both. TOnrej, I created another question for you with the points.
Cheers
Vlad
it might look like this:
type
DataUnion_t = (packed) record
case Integer of
0: (
counter: DmiCounter_t;
);
1: (
counter64: DmiCounter64_t;
);
2: (
displaystring: PDmiString_t;
);
end;
PDmiString_t = ^TDmiString_t; (sounds like PChar)
since you don't post DmiCounter declarations in C, I can't tell
Also, you should give these types a "nicer" Delphi names (e.g. TDataUnion)
;-)
Hope this helps