TIA Array per Variant übergeben und auf Elemente zugreifen.

vollmi

Level-3
Beiträge
5.747
Reaktionspunkte
1.690
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen

Gibt es eine möglichkeit. Ein Array an einen Variant eingang eines Bausteins anzuhängen und dann von diesem Baustein aus auf die Elemente des Arrays zuzugreifen?

Ich möchte also im Baustein keinen Speicher vorhalten um das Array umzukopieren.
Ich möchte im Baustein erfahren wie gross dass das Array ist etc.
Das funktioniert schonmal
Code:
IF NOT IS_ARRAY(#Array) THEN
    #Err := True;
    RETURN; // Wenn kein Array angehängt wurde, Baustein verlassen
ELSE
    #Err := false;
    #Arraygroesse := UDINT_TO_INT(CountOfElements(#Array));
END_IF;

Aber kann ich jetzt aus dem Variant #Array jetzt auch irgendwie die Datentypen der Elemente abfragen.
Auf ein Element schreiben, lesen etc?

mfG René
 
Moin vollmi,

das müsste doch mit EQ_ElemType()* gehen. Dafür müsstest du dann nur Platzhalter vom zu vergleichenden Typ (Bool, Byte usw.) anlegen um auf diese zu vergleichen.

* für FUP / in SCL TypOfElement()
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
TypOfElement gibt den Typ zurück
Blpck move Variant wäre die entsprechende Methode deiner Wahl um die Elemente raus zu bekommen :-)
schau mal hier den FIFO Buffer an- da ist das mit Variant gelöst glaube ich : https://support.industry.siemens.com/cs/ww/de/view/109479728

Muss es Variant sein?
Wenn der Datentyp des Arrays Bekannt ist, kannst du auch einen Array
[*] nehemen und innen dann mit Upper- und Lower_bound die grenzen auslesen. (ab V14)

VG und ein schönes WE
 
MOVE_BLK_VARIANT setzt beim Griff ins Leere, bzw. bei Überschreitung der Arraygrenzen, das ENO-Bit zurück. Auf diese Weise kann man zur Laufzeit die Grenzen erkennen und darauf reagieren. Damit ist man wesentlich versionsunabhängiger.
 
AB V15 gibt's Referenzen... Ist genau was du suchst,oder?
  • Mit "Referenzen" steht eine neue Art von Zeiger zur Verfügung. Referenzen sind typisierte Zeiger, die auf einen konkreten Datentyp verweisen. Wenn Sie Referenzen verwenden, definieren Sie den Datentyp bereits bei der Programmerstellung. Da der Datentyp nicht zur Laufzeit ermittelt werden muss, wird das Programm performanter und übersichtlicher. Durch "Dereferenzieren" können Sie direkt schreibend oder lesend auf die referenzierte Variable zugreifen, ohne die Variable zuvor zu kopieren oder zusätzliche Anweisungen in Ihr Programm einzubinden.
    Voraussetzung für den Einsatz von Referenzen ist eine CPU der Baureihe S7-1500 ab FW V2.5.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
AB V15 gibt's Referenzen... Ist genau was du suchst,oder?

Das ist fast das was ich suche.
Leider kann man so keine unbekannten Arraygrössen übergeben.

Aber so könnte man wenigstens Arrays verschiedener Typen übergeben wenn die Grösse vorher festgelegt wurde.

Ich machs also trotzdem wie RedCali angedacht. Ich gebe ein Undefiniertes Array eines definierten typs an und mach halt für jeden Typ einen Baustein.
 
Ich machs also trotzdem wie RedCali angedacht. Ich gebe ein Undefiniertes Array eines definierten typs an und mach halt für jeden Typ einen Baustein.

In dem Fall mit verschiedenen Arraygrößen UND Typen würde ich auf Block Move Variant zurück greifen, je nachdem wie generisch es am ende sein soll :-)
Denn Block kopieren für verschiedene Typen ist natürlich auch möglich.

Grüße
 
In dem Fall mit verschiedenen Arraygrößen UND Typen würde ich auf Block Move Variant zurück greifen, je nachdem wie generisch es am ende sein soll :-)
Denn Block kopieren für verschiedene Typen ist natürlich auch möglich.

Ich wollte eben genau keinen Speicherplatz reservieren, weder im Lokaldatenstack noch in der Instanz. Darum fällt die Umkopiererei weg.
Interessant wäre es wenn man Konstanten an einer Bausteinschnittstelle durchreichen könnte.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
warum Speicher reservieren???
Bei Block move variant übergibst du einen Variant, intern im Baustein kannst mit isArray typeOfElements und countElemnts dann auf das Array zugreifen.
Wie gesagt, schau dir mal den FIFO Buffer in der LGF an, da ist das mit Variant gelöst glaube ich :)
https://support.industry.siemens.com...view/109479728
 
Zuletzt bearbeitet von einem Moderator:
eben, ich denke das geht genau in deine Richtung.
Übernehmen und anpassen ist ja ohnehin kein Problem, oftmals kann das aber einen Anstoß geben wie man es lösen kann öder könnte.

Schlussendlich ist es aber immer noch so, das jeder seinen eigenen Still verfolgt, und 10 Programmierer 10 Lösungen bringen die am ende das gleiche machen :-)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
warum Speicher reservieren???
Bei Block move variant übergibst du einen Variant, intern im Baustein kannst mit isArray typeOfElements und countElemnts dann auf das Array zugreifen.
Wie gesagt, schau dir mal den FIFO Buffer in der LGF an, da ist das mit Variant gelöst glaube ich :)
https://support.industry.siemens.com...view/109479728

Iiich mach hier mal ne Ausgrabung weil ich gerade an einem Universalbaustein "Push" & "Pull" für das "reindrücken" und "rausziehen" von Elementen in/von einem Array mit undefinierter Grösse und undefiniertem Datentyp bin. Frage bezüglich dem LGF_FIFO: ich hab mir gerade mal den Quellcode angeschaut und festgestellt, dass die intern mit einem Index von 0 bis countOfElements(#buffer) arbeiten (vereinfacht).

Das dürfte dann aber nur mit Arrays funktionieren, die auch bei 0 anfangen, und nicht z.B. bei 1. Gibt es eine Möglichkeit dies auch noch abzufangen? Bei einem array
[*] of Bool (z.B.) kann ich ja mit upper_bound/lower_bound die Arraygrenzen auslesen. Da ich aber einen Variant habe...
Hat da jemand eine Idee?
 
Zuletzt bearbeitet von einem Moderator:
teste es doch einfach mal nach
Ich bin der Meinung das move Block variant immer bei null beginnt, unabhängig davon wie dein Array außerhalb definiert ist
Kann man einfach testen in dem man den FIFO nimmt und ein Array mit anderer untergrenze verwendet ;-)
 
... und festgestellt, dass die intern mit einem Index von 0 bis countOfElements(#buffer) arbeiten (vereinfacht).
Index von 0 bis countOfElements(#buffer)-1 wäre OK.
Aus upper_bound - lower_bound + 1 geht die Anzahl Elemente hervor. Der DatenTyp Variant hat eine feste Länge und legt die Länge der einzelnen Elemente fest.
Damit wird ein Array der passenden Grösse angelegt. Das erste Element bleibt das erste, egal, ob man dafür mit dem Compiler eine Zählung ab 0 oder 1 oder 127 vereinbart hat.
Anscheinend verwaltet der FB das Array völlig eigenständig und muss sich deshalb nicht darum kümmern, welcher IndexBereich anderweitig für eine 1:1- oder nicht-1:1-Kopie davon vereinbart wurde.
Wenn Indizes an den FB übergeben werden, kann er diese anhand von lower_bound umrechnen.

Da ich aber einen Variant habe...
... liegt die Länge der Variablen (mit genügend Reserve) fest. Wenn die Variant-Variable dann später nicht "ausgelastet" wird, weil sie mit einem kürzeren DatenTyp belegt wird, dann stört schlimmstenfalls, dass etliche Bytes nutzlos reserviert wurden.
 
Zuletzt bearbeitet:
Zurück
Oben