[Delphi] C Structs met IF statements naar packed record

Pagina: 1
Acties:

  • Parcye
  • Registratie: Maart 2001
  • Laatst online: 24-08-2017
Ik ben bezig met een project om data om te zetten naar CSV zodat deze op internet geimporteerd kan worden. Het project wordt in Delphi gemaakt, maar ik heb in C wat structs die gebruikt (en dus omgezet moeten worden).

C:
1
2
3
4
5
6
7
8
struct CString
{
    unsigned int m_uiStringSize;
    if (m_uiStringSize > 0)
    {
        wchar_t *m_pString[m_uiStringSize + 1];
    }
};

Dit is omgezet naar het volgende...

Delphi:
1
2
3
4
5
RString = packed record
    StringSize: integer;
    TheString: record end;
    {TheString: array[1..StringSize*2+2] of char}
end;

Ik kan echter de waarde van 'TheString' niet benaderen.

Verder heb ik meer structs met een 'if' er in verwerkt. Voorbeeld:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
struct CContract
{
    unsigned char ContractType;
    if (ContractType == 1)
    {
        CDatum ContractEinde;
    }
    if (ContractType == 2)
    {
        CString Naam;
        CDatum ContractEinde;
    }
};

Volgens mij is dit niet te veranderen door een 'case of' situatie, omdat de record/struct een andere lengte heeft afhankelijk van ContractType.

Iemand die mij opweg kan helpen naar het omzetten van deze structs naar packed records?

"Als je het kan bedenken, kan het gemaakt worden" Parcye - 14 januari 2002


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 18:54

.oisyn

Moderator Devschuur®

Demotivational Speaker

Nou ben ik benieuwd welke C compiler jouw C code toelaat, maar ik gok dat het pseudocode is. De tweede case zou zijn:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
struct CContract
{
    unsigned char ContractType;
    union
    {
        struct
        {
            CDatum ContractEinde; 
        } type1;

        struct
        {
            CString Naam; 
            CDatum ContractEinde; 
        } type2;
    };
};


Geen idee of Delphi een variant voor union heeft, maar anders zou je het met verschillende structs aan kunnen pakken.

Het eerste probleem kun je natuurlijk gewoon oplossen met een array van lengte 1. Die 'record end' gaat natuurlijk niet werken omdat TheString dan geen type heeft.

[ Voor 13% gewijzigd door .oisyn op 25-09-2006 17:49 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Parcye
  • Registratie: Maart 2001
  • Laatst online: 24-08-2017
Het record werkt in Delphi wel, hij leest ook de juist bytes in, ik kan ze echter niet meer benaderen. Maar met 'case ... of' kun je in Delphi de union nabootsen, echter heb ik begrepen dat alle types de zelfde lengte moeten hebben.

In eerste instantie dacht ik zelf ook de de C code psuedocode is/was, maar het schijnt te werken. Zelf heb ik geen C omgeving meer om het mee te testen.

[ Voor 25% gewijzigd door Parcye op 25-09-2006 18:16 ]

"Als je het kan bedenken, kan het gemaakt worden" Parcye - 14 januari 2002


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 18:54

.oisyn

Moderator Devschuur®

Demotivational Speaker

maar het schijnt te werken
Het is iig geen standaard C/C++

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 21:26

Creepy

Tactical Espionage Splatterer

Parcye schreef op maandag 25 september 2006 @ 16:16:
Delphi:
1
2
3
4
5
RString = packed record
    StringSize: integer;
    TheString: record end;
    {TheString: array[1..StringSize*2+2] of char}
end;
TheString is nu een leeg record, dus dat je die niet kan benadering is niet zo vreemd.
Een *char of char[] kan in Delphi ook worden gebruikt alleen is het Delphi type dan pchar.

Maar ik denk dat je beter direct de code kan omschrijven naar een echt native Delphi iets. Een CString is "gewoon" een struct of class om een string te benaderen, iets wat Pascal/Delphi al standaard heeft. Voor het inlezen van een CVS bestand heb je die struct omgezet naar Delphi echt niet nodig.

[ Voor 26% gewijzigd door Creepy op 25-09-2006 18:58 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • Parcye
  • Registratie: Maart 2001
  • Laatst online: 24-08-2017
Het is geen CSV bestand dat ingelezen moet worden maar een .dat bestand met een custom format. Ik wil de data inlezen en omzetten naar CSV.

Dus ik zal hoe dan ook een packed record moeten gebruiken om het in te lezen.

"Als je het kan bedenken, kan het gemaakt worden" Parcye - 14 januari 2002


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Neehoor, je kan ook gewoon stukje voor stukje of byte voor byte inlezen. En waarom probeer je niet eens hoe ver je met de case records in Delphi komt? De rest kan je dan stukje voor stukje doen.

We adore chaos because we like to restore order - M.C. Escher


  • Parcye
  • Registratie: Maart 2001
  • Laatst online: 24-08-2017
Maar maakt dat het niet gelijk erg traag? Als je byte voor byte gaat inlezen en plaatsen....

Als je de structuur weet... kun je toch beter op die manier inlezen?

"Als je het kan bedenken, kan het gemaakt worden" Parcye - 14 januari 2002


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Ja, dat zou iets sneller zijn. Ik beid je een oplossing die werkt, maar je mag ook nog verder zoeken naar een snellere oplossing die misschien helemaal niet bestaat. :)

We adore chaos because we like to restore order - M.C. Escher


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 13-02 09:40

Tomatoman

Fulltime prutser

Er is in Delphi een subtiel verschil tussen de twee onderstaande records:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
type
  TShapeList = (Rectangle, Triangle, Circle, Ellipse, Other);

  TFigure1 = record
    case TShapeList of
         Rectangle: (Height, Width: Real);
         Triangle: (Side1, Side2, Angle: Real);
         Circle: (Radius: Real);
         Ellipse, Other: ();
  end;

  TFigure2 = record
    case TheShape: TShapeList of
         Rectangle: (Height, Width: Real);
         Triangle: (Side1, Side2, Angle: Real);
         Circle: (Radius: Real);
         Ellipse, Other: ();
  end;
Het verschil tussen TFigure1 en TFigure 2 is dat er bij TFigure1 geen ruimte in de record is gealloceerd voor het element TheShape en bij TFigure2 wel. De tweede record is daarom precies de grootte van TShapeList groter dan de eerste record.

Je kunt ook zien dat afhankelijk van de gekozen shape er 0, 1, 2 of 3 reals in de record worden opgeslagen. De grootte van de record is eenvoudigweg de maximale grootte die nodig is om alle elementen op te nemen (dus 3 reals).

Verder nog een stuk tekst uit de help files:
A record type can have a variant part, which looks like a case statement. The variant part must follow the other fields in the record declaration.

To declare a record type with a variant part, use the following syntax.
Delphi:
1
2
3
4
5
6
7
8
9
10
type
  recordTypeName = record
       fieldList1: type1;
        ...
       fieldListn: typen;
       case tag: ordinalType of
          constantList1: (variant1);
          ...
          constantListn: (variantn);
     end;

The first part of the declaration - up to the reserved word case - is the same as that of a standard record type. The remainder of the declaration - from case to the optional final semicolon - is called the variant part. In the variant part,
  • tag is optional and can be any valid identifier. If you omit tag, omit the colon (:) after it as well.
  • ordinalType denotes an ordinal type.
  • Each constantList is a constant denoting a value of type ordinalType, or a comma-delimited list of such constants. No value can be represented more than once in the combined constantLists.
  • Each variant is a semicolon-delimited list of declarations resembling the fieldList: type constructions in the main part of the record type. That is, a variant has the form
    Delphi:
    1
    2
    3
    
    fieldList1: type1;
      ...
    fieldListn: typen;

    where each fieldList is a valid identifier or comma-delimited list of identifiers, each type denotes a type, and the final semicolon is optional. The types must not be long strings, dynamic arrays, variants (that is, Borland.Vcl.Variants.Variant types), or interfaces, nor can they be structured types that contain long strings, dynamic arrays, variants, or interfaces; but they can be pointers to these types.

Een goede grap mag vrienden kosten.


  • Parcye
  • Registratie: Maart 2001
  • Laatst online: 24-08-2017
Ik ben er achter waar mijn voorbeeld code vanaf komt, dat is een bin template van de 010 editor.

"Als je het kan bedenken, kan het gemaakt worden" Parcye - 14 januari 2002

Pagina: 1