Link to home
Start Free TrialLog in
Avatar of vladh
vladhFlag for Canada

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
Avatar of TOndrej
TOndrej

Hi vladh,
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
Avatar of vladh

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
Avatar of Romi Kuntsman
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... ?

Avatar of vladh

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

> 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.
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)".
Avatar of vladh

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
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
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
Avatar of Romi Kuntsman
Romi Kuntsman
Flag of Israel image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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
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
No difference in action. But wer'e talking about translating code, and why I wrote is the exact translation from what was given.

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 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.
Avatar of vladh

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