String in Array of String schreiben

Zuviel Werbung?
-> Hier kostenlos registrieren
Ich möchte nochmals auf die Adressierung zurückkommen.

Ich habe ein Struct mit 21 Einträgen

z.B
Code:
TYPE ST_Diag :
STRUCT


    SFCCurrentStepRef            :STRING (40);
    SFCCurrentStepSystem                 :STRING (40);
        etc....

Code:
    Diag:ST_DIAG;

Nun mache ich den Zugriff auf dieses Struct mit einem Pointer

Code:
ArrayDiagTemp := ADR (Diag);

Code:
ArrayDiagTemp:  POINTER TO ARRAY [0.. n] OF STRING;                                    (*This is the diag array which hold all the temp machine status*)
                                                        (*to access the diag infos more easly there is a struct defined which points to the same array*)
                                                        (*use this array only in *)


Frage 1;
Wieviel Speicherplatz wird nun für das ArrayDiagTemp reserviert?
Könnte dies auch mit STRING (40) limitiert werden da die Daten im Struct nicht grösser sein können?
Was passiert nun wenn das Array keine explizite hat Zuweisung hat?
Es werden 80 Byte reserviert pro Array reserviert, oder?
Da mein Eintrag im Struct mit 40 Byte limitiert ist bleiben dann der Speicherplatz von 41-80 immer leer?

Frage 2;
Warum zeigt es nur bei der ersten Zeile im Array den Korrekten Text vom Struct an?
Ist jetzt nicht zu erwarten dass beim Array am Speicherplatz 81 sich der nächste String befindet?
Gemäss vorherigem Post sind die Daten im ASCII abgelegt. Warum ist nun aber 1 Eintrag korrekt und der Rest ist Müll?

Frage 3;
Warum befinde ich mich im Speicherabbild der SPS?
Ich hätte erwartet, dass ich mich lediglich im Speicher vom ArrayDiagTemp befinde.

Sorry dass ich hier nochmals nachhacken muss, aber es lässt mich nicht in Ruhe wenn ich die Funktionsweise nicht verstehe.
Danke für Eure Unterstützung?

Hi,

ich hoffe, dass in naechsten zwei Tagen alles beantworten kann.
Dafuer brauche ich einige Beispiele, um alles nachvollziehbar zu erklaeren.

Irek
 
Das lässt sich wohl auch sofort beantworten. Die einzelnen Strings des Arrays müssen natürlich die gleiche Startadresse haben wie die im Struct, also:
Code:
ArrayDiagTemp:  POINTER TO ARRAY [0.. n] OF STRING(40);
 
In Deinem Struct ST_Diag stehen die String(40) hier:
SFCCurrentStepRef Byte 0..40
SFCCurrentStepSystem Byte 41..81
Nächster String Byte 82..122
usw.
Im Array, das an der gleichen Speicheradresse beginnt wie die Struct-Instanz, stehen die String(80) dagegen hier:
ArrayDiagTemp^[0] Byte 0..80
ArrayDiagTemp^[1] Byte 81..161
ArrayDiagTemp^[2] Byte 162..242
usw.
ST_Diag.SFCCurrentStepRef hat noch die gleiche Startadresse wie ArrayDiagTemp^[0], deshalb wird der Text auch richtig angezeigt.
Danach passen aber die Startadressen der Struct-Einträge nicht mehr zu denen der Array-Felder. Deshalb s. #22
 
Anzahl:=0;
while _i < ArrayItem_Max+1 do
if ArraItem[x].String <> '' then (*hier wird nach einen String gesucht, wenn nichts da, wird der naechste Arrayfeld bearbeitet*)
NewArrayItem[Anzahl].String:=ArraItem[x].String(*und wenn was da, dann in neuen Array kopieren*)
Anzahl:=Anzahl+1;(*Index erhoehen, sonst wird alles ueberschrieben*)
end_if;
_i:=_i+1;
end_while;


Absolut einverstanden.
Wenn ich aber das Array durchsuche, dann müsste ich ja egal wie das Array Definiert ist die Einträge wieder finden.
Das Struct kann lediglich den Speicherplatz 0-40 vom Array in Anspruch nehmen.
Speicherplatz 40-80 sollte eigentlich nie belegt werden, oder?
Der Anfang der Daten müsste sich dann an Stelle 0 (Das sehen wir), 81, 162 etc. befinden.

Danke für Eure Hilfe
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Du hast doch eine Instanz des Structs, während das Array nur als Pointer auf die Startadresse des Structs zeigt. Die Anordnung der Daten im Speicher wird also durch das Struct bestimmt, seine einzelnen Strings beginnen an Byte 0, 41, 82, 123 usw. Wenn Du über den Array-Pointer auf die Strings zugreifen willst, müssen die Array-Felder an genau den gleichen Speicheradressen beginnen, also auch als "String(40)" deklariert sein. Da bleibt kein freier Bereich. Wenn im Struct zwischen den Strings keine Bytes frei sind, dann kann und darf das im Array auch nicht sein.
 
Du hast doch eine Instanz des Structs, während das Array nur als Pointer auf die Startadresse des Structs zeigt. Die Anordnung der Daten im Speicher wird also durch das Struct bestimmt, seine einzelnen Strings beginnen an Byte 0, 41, 82, 123 usw. Wenn Du über den Array-Pointer auf die Strings zugreifen willst, müssen die Array-Felder an genau den gleichen Speicheradressen beginnen, also auch als "String(40)" deklariert sein. Da bleibt kein freier Bereich. Wenn im Struct zwischen den Strings keine Bytes frei sind, dann kann und darf das im Array auch nicht sein.

Hi,

habe etwas vorbereitet, sollte (ich hoffe es) wieterhelfen, falls Fragen noch offen Message an dieser Stelle reicht aus.
Vor deinem Problem habe ich vor einigen Tage selbst kapituliert, jetzt ist alles Einfach, Stringbreite deklariert = Anzahl Bytes + 1 fuer Stringende im Speicher der PLC.
Sollst du Online testen, bitte nach Aenderung der Werte Onlinereset durchfueren.

PROGRAM MAIN
VAR
Array1:ARRAY[1..4] OF STRING(1):='1','2','3','4';
Array2:ARRAY[1..4] OF STRING(2):='1','2','3','4';
Array3:ARRAY[1..4] OF STRING(4):='1','2','3','14';
_size_Array1:INT;
_size_Array2:INT;
_size_Array3:INT;
_size_Item_Array1:INT;
_size_Item_Array2:INT;
_size_Item_Array3:INT;
_pointer1: POINTER TO BYTE;(* bei 1 Ergebnis=16#49 also ASCI '1'*)
_pointer2: POINTER TO WORD;
_pointer3: POINTER TO DWORD;
_pointer1A: POINTER TO STRING(1);
_pointer2A: POINTER TO STRING(2);
_pointer3A: POINTER TO STRING(4);
_adr1:WORD;
_adr2:WORD;
_adr3:WORD;

_gesuchte_String1:STRING(1);(* bei 1 Ergebnis= '1' also direkt das Zeichen !*)
_gesuchte_String2:STRING(2);
_gesuchte_String3:STRING(4);

_gesuchte_String1A:STRING(1);(* bei 1 Ergebnis= '1' also direkt das Zeichen !*)
_gesuchte_String2A:STRING(2);
_gesuchte_String3A:STRING(4);

END_VAR

(***********************************************************)
_adr1:=ADR(Array1);
_size_Array1:=SIZEOF(Array1);
_size_Item_Array1:=SIZEOF(Array1[1]);(*Deklariert 1 Zeichen also 1Byte, werden aber 2Byte benoetigt fuer die Kennung "Stringende"*)
_adr2:=ADR(Array2);
_size_Array2:=SIZEOF(Array2);
_size_Item_Array2:=SIZEOF(Array2[1]);(*Deklariert 2 Zeichen also 1Byte, werden aber 3Byte benoetigt fuer die Kennung "Stringende"*)
_adr3:=ADR(Array3);
_size_Array3:=SIZEOF(Array3);
_size_Item_Array3:=SIZEOF(Array3[1]);(*Deklariert 4 Zeichen also 4Byte, werden aber 5Byte benoetigt fuer die Kennung "Stringende"*)

_pointer1A:=_adr1;
_pointer2A:=_adr1;
_pointer3A:=_adr1;
(*gesuchte String mit Breite 1;2;4 Zeichen *)
_gesuchte_String1:=_pointer1A^;
_gesuchte_String2:=_pointer2A^;
_gesuchte_String3:=_pointer3A^;

_pointer1A:=_adr1;
_pointer2A:=_adr1+4;
_pointer3A:=_adr1+6;

_gesuchte_String1A:=_pointer1A^;
_gesuchte_String2A:=_pointer2A^;
_gesuchte_String3A:=_pointer3A^;

_pointer1A:=_adr3;
_pointer2A:=_adr3+10;
_pointer3A:=_adr3+15;

_gesuchte_String1A:=_pointer1A^;
_gesuchte_String2A:=_pointer2A^;
_gesuchte_String3A:=_pointer3A^;

(********************************************************)
 
Zuletzt bearbeitet:
Zurück
Oben