Pointer in ein Byte Array umwandeln

Zuviel Werbung?
-> Hier kostenlos registrieren
@Larry hast wieder recht ich kann das nicht in ner Funktion machen, muss wahrscheinlich in nen FB was mir eigentlich wieder nicht gefällt.
Jetzt weiß ich warum ich, warum ich das damals gelassen hatte
 
Sorry ... du mußt schon wissen, was du haben willst ...

Aber vielleicht ist ja auch der andere von mir angedeutete Ansatz etwas sinnvoller ... (Beitrag #14)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ich arbeite schon mit send und receive, aber wie du dass da gemeint hast habe ich nicht verstanden. bei mir muss auf jedenfall alles in den SendeBuffer rein bevor ich es senden kann.
 
Ich meinte es so :
Alles, was du schon in SCL hast, das kannst du auch in SCL komfortabel bewurschteln ...
Du legst dir also in deinem Baustein ein ARRAY_of_Byte in der von dir benötigten Größe an. Außerdem legst du dir im TEMP-Bereich einen ANY-Pointer an. Und dann geht es etwa so :
Code:
FUNCTION_BLOCK FB511 
VAR_INPUT
   CP_ADDR             : INT ;    // Perepherie-Adresse des CP340
END_VAR
   
VAR
   Receive        : P_RCV ;
   Send           : P_SEND ;
(*
V24_STAT(LADDR := CP_ADDR // IN: INT
         ,DTR_OUT := Status.DTR // OUT: BOOL
         ,DSR_IN := Status.DSR // OUT: BOOL
         ,RTS_OUT := Status.RTS // OUT: BOOL
         
   Receive_Puffer : ARRAY[1..6] OF BYTE ;
   
END_VAR
  
VAR_TEMP
   DatenQuelle_Adr : INT ;
   DatenQuelle_Any : ANY ;
   DatenQuelle_struct AT DatenQuelle_Any : STRUCT
                   ID_Code   : BYTE ;   
                   DataTyp   : BYTE ;
                   Anzahl    : WORD ;
                   DB_Nr     : WORD ;
                   SpeicherPtr : DWORD ;
                END_STRUCT ;
END_VAR
  
BEGIN   
   DatenQuelle_Any := Receive_Puffer ;
   DatenQuelle_Adr := DWORD_TO_INT(SHR (IN:=(DatenQuelle_struct.SpeicherPtr AND dw#16#00FF_FFFF) , n:=3)) ;
                   
   Receive  (EN_R   := true           
            ,R      := FALSE                        
            ,LADDR  := CP_ADDR    
            ,DB_NO  := WORD_TO_INT(DatenQuelle_struct.DB_Nr)
            ,DBB_NO := DatenQuelle_Adr 
            ) ; 
END_FUNCTION_BLOCK
... das ist jetzt natürlich ein Auszug aus einem meiner Programme. Es könnte ggf. etwas fehlen :)(). das Prinzip sollte aber erkennbar sein ...
 
hallo larry,

das kann ich bei mir so leider nicht nutzen. wie gesagt ich habe einen RingPuffer und an den führt kein Weg vorbei.
Zudem kenne ich die genaue Byte-Array größe nicht.
Deswegen mit Pointer. Egal ich finde schon einen Weg wie es bei mir klappt.
Trotzdem vielen Dank an alle für die Hilfe.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Du mußt es selbst wissen ...

allerdings :
- wie fütterst du einen FB-Send (oder -Receive) mit einem Ring-Puffer ? Die können nur aufsteigend ...
- wenn du die Puffer-Größe nicht kennst - wie sendest und empfängst du dann jetzt ? Vario gibt es bei Step7 nicht ...
- wo ein Wille ist, da ist auch ein Weg ...

Gruß
Larry
 
das senden und empfangen klappt schon seit ner weile problemlos ich wollte nur einen neuen Datentypen hinzufügen bzw. eigentlich 2 die ich senden möchte. Die normalen wie strings timestamps byte bool, reals int usw. geht alles ohne probleme.
Der neuen Datentyp ist der BLOB und ListenElemente wobei ich letzteres fraglich finde, aber von mir wurde gefordert strukturen über tcp senden zu können. ich muss halt vorher alles in mein Ringbuffer packen. weil alles in der richtigen reihenfolge rausgesendet werden muss.
 
Du könntest ja deinen Ringpuffer (wofür immer du den brauchst) in den gleichen FB packen in dem auch der Sende-Puffer für den FB-Send ist. Nun kannst du alles komfortabel hin und her kopieren (ohne Klimmzüge).

...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Warum muss es eigentlich über einen Zeiger sein? Zeigerhandling (bzw. die Parametertyp POINTER oder ANY) ist in Siemens-SCL äußerst unkomfortabel.
Bei einem SPS-Programm stehen die Array-Größen üblicherweise bei der Übersetzung des Programmes fest.

Wenn der Puffer unbedingt außerhalb der Funktion sein muss, kannst du es auch lösen indem du das Array als Parameter übergibst. In dem Datenbaustein wo der Puffer später angelegt wird, muss dieser den gleichen Datentyp und gleiche Arraygröße wie der Parameter haben.
Code:
CONST
    BUFSIZE := 100;
END_CONST

VAR_IN_OUT
    byteArr : ARRAY[0..BUFSIZE] OF BYTE;
END_VAR

Wenn du einen FB verwendest musst du darauf achten den Parameter als VAR_IN_OUT anzulegen, denn nur dann wird dieser intern als Pointer übergeben.
Nur so kann man SCL dazu bringen das Dereferenzieren des Pointers zu übernehmen.
Wenn du es unbedingt als Datentyp "Pointer" haben möchtest, musst du dich wohl oder übel mit der aufwändigen Zerlegung wie in den diversen Codebeispielen hier herumärgern.
 
Zuletzt bearbeitet:
buffer größe steht nicht fest, deswegen muss ich es über Pointer machen. Aber irgendwie kann ich bei den scheiß Pointern kein AT machen in Funktionen. Und Funtkionsbaustein ist tabu für mich, dass muss irgendwie in ne Funktion rein. ich sehe mittlerweile nur noch den weg über any pointer und blockmov. ist zwar nicht das was ich wollte, weil ich meine überwachung umgehen muss aber was anderes fällt mir nicht ein.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo habs jetzt so gelöst, kommen zumindest mal keine Fehler.
Im Prinzip dein Vorschlag Larry nur mit ANYs, weil Pointer hat der Compiler gemeckert.
Obs wirklich geht, teste ich gleich.

Code:
FUNCTION WriteBlobParam: VOID
VAR_INPUT 
    id      : DWORD;
    val     : ANY;
    iLen    : INT;
END_VAR
VAR_TEMP
    pos:INT;
    pAny : ANY;
    val_REF AT pAny: typANY;
    iStart  : INT;
    iEnd    : INT;
    dwBytePointer : DWORD ; 
END_VAR

pAny    := val;

dwBytePointer := val_REF.dwBytePointer AND dw#16#00FF_FFFF ;
iStart := DWORD_TO_INT(SHR (IN:=dwBytePointer , n:=3)) ;

iEnd    := iStart + iLen -1;

DCI_WriteParamMeta(id:=id,tp:=10);
FOR pos:=iStart TO iEnd DO
    DCP_WriteByte(WORD_TO_BLOCK_DB(INT_TO_WORD(val_REF.iDB_Number)).DB[pos]);
END_FOR;

END_FUNCTION
 
Zurück
Oben