Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Ergebnis 1 bis 9 von 9

Thema: TwinCAT V2.11: Vergleichen von Strukturen

  1. #1
    Registriert seit
    19.05.2008
    Beiträge
    651
    Danke
    118
    Erhielt 136 Danke für 105 Beiträge

    Frage


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo Ihr,

    bisher war ich der Meinung, dass der Umgang mit Strukturen bei TwinCAT recht einfach und unkompliziert ist. Kann ich doch Strukturen direkt in ein Array of STRUCT kopieren und umgekehrt…

    Code:
    VAR
      sRezept       : ARRAY[1..50] OF Rezeptur_01;  (* Rezept-Daten *)
      sAktRezept  : Rezeptur_01;  (* aktuelles Rezept *)
    END_VAR
       
      sAktRezept := sRezept[11];
    Jetzt wollte ich prüfen, ob zwei Strukturen die gleichen Inhalte haben.
    Code:
    IF sRezept[11] = sRezept[12] THEN
    …
    Leider bekomme ich Übersetzungsfehler 4010 gemeldet. (Unverträgliche Typen: Kann '<Name>' nicht in '<Name>' konvertieren.)

    Mache ich was falsch, oder geht das tatsächlich nicht?!?
    Klar kann ich den Inhalt der Rezepte einzeln vergleichen. Es wäre aber schon schön, wenn das der Compiler machen würde…

    Gruß
    Chräshe
    -----------------------------

    PS: Habe diesen Beitrag gefunden. Allerdings komme ich mit dem Befehl MEMCMP auch nicht weiter.
    Code:
     
    Ungleich := MEMCMP(sRezept[11], sRezept[12], SIZEOF(sRezept[12]));
    Nur wird jetzt der Fehler 4012 gemeldet (Unzulässiger Typ für Eingang '<Name>' von '<Name>' : Kann'<Name>' nicht in '<Name>' konvertieren.)
    Zitieren Zitieren TwinCAT V2.11: Vergleichen von Strukturen  

  2. #2
    Avatar von Chräshe
    Chräshe ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    19.05.2008
    Beiträge
    651
    Danke
    118
    Erhielt 136 Danke für 105 Beiträge

    Idee

    Hallo Ihr,

    wer lesen kann ist klar im Vorteil: In der ersten Antwort war bereits die Lösung…
    … da muss man sich erst mal dran gewöhnen.

    Gruß
    Chräshe
    Zitieren Zitieren Problem gelöst…  

  3. #3
    Registriert seit
    12.04.2010
    Beiträge
    300
    Danke
    22
    Erhielt 54 Danke für 52 Beiträge

    Standard

    Hi
    Code:
     
    Ungleich := MEMCMP(sRezept[11], sRezept[12], SIZEOF(sRezept[12]));
    Also normalerweise würde das so geschrieben werden

    Code:
     
    Ungleich := MEMCMP(ADR(sRezept[11]), ADR(sRezept[12]), SIZEOF(sRezept[12]));
    hmm, gibts ja ADR() oder ? Das stammt jetzt von der B&R Welt

    dann sollte es jedenfalls gehen. Selber geschrieben geht natürlich auch, musst du aber damit rechnen dass die Funktion schon etwas länger braucht. Zumindest würde man anfangs mal DINT vergleichen (spart man sich schon einige Schleifen-Durchläufe) und dann bytes...

  4. #4
    Avatar von Chräshe
    Chräshe ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    19.05.2008
    Beiträge
    651
    Danke
    118
    Erhielt 136 Danke für 105 Beiträge

    Böse

    Ja das ADR hatte ich übersehen, es darf nur die Anfangsadresse der Struktur der Funktion MEMCMP übergeben werden. Das ist auch alles korrekt dokumentiert – man muss eben nur lesen...

    Zufrieden bin ich mit der Erkenntnis trotzdem nicht. Wenn folgender Code funktioniert wie ich erwarte,

    sAktRezept := sRezept[11]; (* Funktioniert *)

    was soll dann hier ein Problem darstellen?

    IF sRezept[11] = sRezept[12] THEN (* - geht nicht - *)
    ...
    Da würde doch jeder Anfänger zurechtkommen, weil es logisch und übersichtlich ist, was man hiervon eher nicht sagen kann:

    Ungleich :=
    MEMCMP(ADR(sRezept[11]), ADR(sRezept[12]), SIZEOF(sRezept[12]));
    (* Funktioniert *)

    4 Funktionen und eine Hilfsvariable....

  5. #5
    Registriert seit
    12.04.2010
    Beiträge
    300
    Danke
    22
    Erhielt 54 Danke für 52 Beiträge

    Standard

    Zitat Zitat von Chräshe Beitrag anzeigen
    sAktRezept := sRezept[11]; (* Funktioniert *)

    was soll dann hier ein Problem darstellen?

    IF sRezept[11] = sRezept[12] THEN (* - geht nicht - *)
    ja, gebe ich dir recht...

    aber


    Ungleich := MEMCMP(ADR(sRezept[11]), ADR(sRezept[12]), SIZEOF(sRezept[12])); (* Funktioniert *)

    4 Funktionen und eine Hilfsvariable....
    stimmt so nicht ganz:

    Code:
    if (MEMCMP(ADR(sRezept[11]), ADR(sRezept[12]), SIZEOF(sRezept[12])) <> 0) then
    ... (ungleich)
    else
    ... (gleich)
    endif
    keine Hilfsvariable, ADR ist keine Funktion sondern wird vom Compiler übersetzt genauso wie sizeof() keine Laufzeitfunktion ist sondern Compiler Angelegenheit. D.h. zur Laufzeit hast du 2 Adressen und 1 Größe für Speichervergleich....

    (wieder: ich denke dass das bei dir auch so funktionieren wird, das hier entspricht B&R Code)

    bg
    bb

  6. #6
    Registriert seit
    08.01.2007
    Beiträge
    54
    Danke
    1
    Erhielt 10 Danke für 8 Beiträge

    Standard

    ADR ist keine Funktion sondern wird vom Compiler übersetzt genauso wie sizeof() keine Laufzeitfunktion ist sondern Compiler Angelegenheit. D.h. zur Laufzeit hast du 2 Adressen und 1 Größe für Speichervergleich....
    unter vom Compiler übersetzt verstehe ich das der Compiler den Ausdruck mit einem Wert ersetzt. Dem ist jedoch nicht so.
    sizeof und adr sind für mich ganz klar Funktionen. Dort wird nichts ersetzt sondern zur laufzeit berechnet.

  7. #7
    Registriert seit
    12.04.2010
    Beiträge
    300
    Danke
    22
    Erhielt 54 Danke für 52 Beiträge

    Standard

    Zitat Zitat von soma Beitrag anzeigen
    .. Dem ist jedoch nicht so.
    sizeof und adr sind für mich ganz klar Funktionen. Dort wird nichts ersetzt sondern zur laufzeit berechnet.
    Würde ich mal nein sagen, siehe z.B.

    http://de.w3support.net/index.php?db=so&id=671790


    und ADR() ist sowieso nur das Gegenstück zu ANSI-C "&" -> Address-Funktion
    ...

  8. #8
    Registriert seit
    08.01.2007
    Beiträge
    54
    Danke
    1
    Erhielt 10 Danke für 8 Beiträge

    Standard

    ADR
    Wenn ich mir eine Funktion schreibe die als Parameter einen Pointer hat,
    dann kann ich innerhalb der Funktion adr auf den Pointer aufrufen.
    Da der Compiler nicht weiß womit ich die Funktion aufrufe, kann er die Adresse nicht zum Compilierzeitpunkt berechnen.
    De facto muss das Programm jedoch für jede Variable die Speicheradresse wissen, somit stelle ich mir vor, dass adr als Funktion sich dieses Tables bedient, jedoch nicht mit einem Wert ersetzt wird.

    SIZEOF
    Bei SizeOf bin ich mir mittlerweile nicht mehr sicher. Natürlich greift hier ebenfalls die oben aufgeführte Annahme, jedoch muss ich den Datentyp auf den der Pointer zeigt angeben. somit kann die Größe ersetzt werden da sie sich nicht verändern kann.

  9. #9
    Registriert seit
    12.04.2010
    Beiträge
    300
    Danke
    22
    Erhielt 54 Danke für 52 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Zitat Zitat von soma Beitrag anzeigen
    ADR





    Wenn ich mir eine Funktion schreibe die als Parameter einen Pointer hat,
    dann kann ich innerhalb der Funktion adr auf den Pointer aufrufen.
    Da der Compiler nicht weiß womit ich die Funktion aufrufe, kann er die Adresse nicht zum Compilierzeitpunkt berechnen.
    De facto muss das Programm jedoch für jede Variable die Speicheradresse wissen, somit stelle ich mir vor, dass adr als Funktion sich dieses Tables bedient, jedoch nicht mit einem Wert ersetzt wird.
    Hi,

    also ich versuch mir das einfach so wie bei einem C-Programm vorzustellen und ich glaube dass ich damit nicht so falsch liege. Es ist doch so dass bei ADR(Var_X) der Compiler weiß wo die Var_X im Variablenspeicher liegt. Und das wird eingetragen.

    Wenn das immer zur Laufzeit bestimmt werden würde, das wäre ja ein Wahnsinn an Resourcen-Verschwendung.

    Wenn du in deinem Projekt Variablen dazufügst, wird ja immer der entsprechende Programmteil compiliert (lokal oder global, je nachdem). Das wäre ja dann gar nicht notwendig wenn zur Laufzeit das alles gemacht würde. z.B. du erweiterst eine globale Variable in Form eines Array von Var_X[5] --> Var_X[6]. Es wird das gesamte Projekt kompiliert, da sich das Datenabbild geändert hat und unter Anderem die ADR() Parameter neu bestimmt werden müssen...


    ... der compiler nicht weiß ....

    Der Compiler weiß natürlich genau mit was du die Funktion aufrufst.

    Die Zielfunktion weiß nicht woher die Adresse kommt, aber das liegt im Verantwortungsbereich des Programmierers hier die richtigen Parameter zu verwenden

    z.B.
    memcpy(ADR(x1), .....)


    compiler weiß dass x1 verwendet wird.


    int memcpy(unsigned char * pCH1, .... )

    den compiler interessiert nicht woher pCH1 kommt, der Programmierer ist verantwortlich dass das zusammenpasst (die Datentypen))
    Geändert von bits'bytes (10.08.2011 um 15:34 Uhr) Grund: ... der compiler nicht weiß ....

Ähnliche Themen

  1. SCL indirekte Adressierung von Strukturen
    Von Anonymous im Forum Simatic
    Antworten: 24
    Letzter Beitrag: 10.02.2016, 19:10
  2. In Arrays und Strukturen denken
    Von vollmi im Forum CODESYS und IEC61131
    Antworten: 8
    Letzter Beitrag: 18.10.2011, 13:35
  3. Strukturinhalte vergleichen unter TwinCAT
    Von grosser_marco im Forum CODESYS und IEC61131
    Antworten: 6
    Letzter Beitrag: 23.01.2009, 08:40
  4. Antworten: 2
    Letzter Beitrag: 12.05.2006, 07:54
  5. S7 200 Strukturen bzw. UDT. Gibt es das nicht?
    Von plc_tippser im Forum Simatic
    Antworten: 5
    Letzter Beitrag: 17.09.2004, 10:59

Stichworte

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •