RSC DataAccess service with Struct contening array or struct in CPP

Hi,
I define the following struct in plcnext
MonElement : Struct
CurrentA : INT;
End_Struct;
StuctWithStruct:STRUCT
Repetition:UINT;
Valid:BOOL;
OneStruct:MonElement;
END_STRUCT;

With the following code, the 2 first element of the struct is correcty written. The struct element is not updated but the service don't issue any error (return code is DataAccessError::None  
  
      Arp::Plc::Gds::Services::WriteItem structItem;  
      structItem.PortName = "Arp.Plc.Eclr/SwS";  
      structItem.Value = RscVariant<512>::CreateStructVariant(3);  
  
      dataItems.WriteNext(structItem);  
      // Create an RscStructWriter for the struct  
      RscStructWriter<512> structWriter{ structItem.Value };  
  
      structWriter.WriteNextField((Arp::uint16)1);  
      structWriter.WriteNextField((Arp::boolean)true);  
  
      //ajout du tableau de structure de 20 element de 3 membres  
      RscVariant<512> OneStruct = RscVariant<512>::CreateStructVariant(1);  
      // Write the array item to the enumerator *before* creating the RscArrayWriter  
      structWriter.WriteNextField(OneStruct);  
  
      RscStructWriter<512> structWriter2{ OneStruct};  
      structWriter2.WriteNextField((Arp::uint16)2);  
          
      dataItems.EndWrite();  
  
  
With a tab in a struct   with the following declaration and code the error returned is typeMismatch,   
  
Struct declaration in plc next:  
  TabUINT : Array [0..1] of UINT;  
  
        StuctWithTab:STRUCT  
        Repetition:UINT;  
        Valid:BOOL;  
        OneTab:TabUINT;  
        END_STRUCT;  
  Arp::Plc::Gds::Services::WriteItem structItem;  
      structItem.PortName = "Arp.Plc.Eclr/SwT ";  
      structItem.Value = RscVariant<512>::CreateStructVariant(3);  
  
      dataItems.WriteNext(structItem);  
      // Create an RscStructWriter for the struct  
      RscStructWriter<512> structWriter{ structItem.Value };  
  
      structWriter.WriteNextField((Arp::uint16)1);  
      structWriter.WriteNextField((Arp::boolean)true);  
      //Add array of 2 uint16  
      RscVariant<512> OneTab = RscVariant<512>::CreateArrayVariant(2, RscType::Uint16);  
      // Write the array item to the enumerator *before* creating the RscArrayWriter  
      structWriter.WriteNextField(OneTab);  
      RscArrayWriter ArrayWriter{ OneTab };  
      ArrayWriter.WriteNext((Arp::uint16)1);  
      ArrayWriter.WriteNext((Arp::uint16)2);  
     dataItems.EndWrite();  
  
  
As their is no sample of writing Struct containing array or other struct is my code correct or is a problem somewhere?  
  
Regards

Sorry for the delay.
Regarding the second issue - a structure containing an array - I can’t see what the problem is in your code.
This works for me (AXC F 2152 FW 2022.6, Toolchain version 2022.0, PLCnext Engineer version 2022.6):

**PLCnext Engineer types**

UINT_ARRAY_0_9 : ARRAY[0..9] OF UINT;
   STRUCT_TYPE3 : STRUCT
        MyBoolean : BOOL;
        MyUInt16  : UINT;
        MyFloat32 : REAL;
        MyString  : STRING;
        MyArray   : UINT_ARRAY_0_9;    
    END_STRUCT  

PLCnext Engineer global variable declarationimage.pngC++ code

// Write the Struct port name and value
    // Create the RscVariant representing the struct, with five fields
    Arp::Plc::Gds::Services::WriteItem structItem;
    structItem.PortName = "Arp.Plc.Eclr/Globby3";
    structItem.Value = RscVariant<512>::CreateStructVariant(5);
    // Write the struct item to the enumerator *before* creating the RscStructWriter
    dataItems.WriteNext(structItem);
    // Create an RscStructWriter for the struct
    RscStructWriter<512> structWriter{ structItem.Value };
    // Fill the RSC Struct Variant with values
    // The fields are written in the order that they are declared
    structWriter.WriteNextField((Arp::boolean)true);
    structWriter.WriteNextField((Arp::uint16)42);
    structWriter.WriteNextField((Arp::float32)42.31);
    // Create an RscString variable to write to the next struct element
    // IMPORTANT: The maximum size of the RscString MUST be the same as the maximum string size of the RscStructWriter object,
    Arp::System::Rsc::Services::RscString<512> myString("String from C++");
    structWriter.WriteNextField(myString);
    // Create an RscVariant for the array field
    RscVariant<512> arrayField = RscVariant<512>::CreateArrayVariant(10, RscType::Uint16);
    // Write the field to the struct
    structWriter.WriteNextField(arrayField);
    // Get an array writer
    RscArrayWriter arrayFieldWriter{ arrayField };
    // Fill the RSC Array Variant with RscType::UInt16 values
    arrayFieldWriter.WriteNext((Arp::uint16)42);
    arrayFieldWriter.WriteNext((Arp::uint16)142);
    arrayFieldWriter.WriteNext((Arp::uint16)242);

Resultimage.png
I will look into the other issue you mentioned.

Hi Martin , i tested your code and finally find the mistake on mine.

structItem.PortName = "Arp.Plc.Eclr/SwT ";

The trailing withespace on the portname is the cause of the problem but think the Error code returned by API must be Arp::Plc::Gds::Services::DataAccessError::NotExists and not Arp::Plc::Gds::Services::DataAccessError::TypeMismatch.

Just coming back to the first issue in your original question - a structure containing a structure.
I am afraid that once again I can’t see what the problem is in your code.
This works for me (AXC F 2152 FW 2022.6, Toolchain version 2022.0, PLCnext Engineer version 2022.6):
PLCnext Engineer types

STRUCT_TYPE4 : STRUCT
        MyInt16   : INT;
    END_STRUCT
    STRUCT_TYPE5 : STRUCT
        MyBoolean : BOOL;
        MyUInt16  : UINT;
        MyFloat32 : REAL;
        MyString  : STRING;
        MyStruct  : STRUCT_TYPE4;
    END_STRUCT

PLCnext Engineer global variable declarationimage.pngC++ code

// Write the Struct port name and value
    // Create the RscVariant representing the struct, with five fields
    Arp::Plc::Gds::Services::WriteItem structItem;
    structItem.PortName = "Arp.Plc.Eclr/Globby5";
    structItem.Value = RscVariant<512>::CreateStructVariant(5);
    // Write the struct item to the enumerator *before* creating the RscStructWriter
    dataItems.WriteNext(structItem);
    // Create an RscStructWriter for the struct
    RscStructWriter<512> structWriter{ structItem.Value };
    // Fill the RSC Struct Variant with values
    // The fields are written in the order that they are declared
    structWriter.WriteNextField((Arp::boolean)true);
    structWriter.WriteNextField((Arp::uint16)42);
    structWriter.WriteNextField((Arp::float32)42.31);
    // Create an RscString variable to write to the next struct element
    // IMPORTANT: The maximum size of the RscString MUST be the same as the maximum string size of the RscStructWriter object,
    Arp::System::Rsc::Services::RscString<512> myString("String from C++");
    structWriter.WriteNextField(myString);
    RscVariant<512> structField = RscVariant<512>::CreateStructVariant(1);
    structWriter.WriteNextField(structField);
    RscStructWriter<512> structFieldWriter{ structField };
    // Fill the RSC Struct Variant with an RscType::Int16 value
    structFieldWriter.WriteNextField((Arp::int16)42);

Resultimage.png

Martin thanks for you help, i don’t change my code but after trying yours mine is working without any code change.