How to implement struct

Questions regarding the use of the C++ SDK for Server or Client development or integration into customer products ...

Moderator: uasdkcpp

Post Reply
Lafond
Hero Member
Hero Member
Posts: 25
Joined: 14 Oct 2008, 12:55

How to implement struct

Post by Lafond »

Hi

Using your C++ SDK, how can I implement a complex DataType like
struct Complex
{
float real;
float imaginary;
}

Do I have to follow the same pattern as UaRange and down to the UA Stack with opcua_Range with ExtensionObject or does the SDK provide a shorter efficient way?
Do you have an example?

Thanks
Last edited by Lafond on 07 Feb 2013, 10:48, edited 1 time in total.

User avatar
Support Team
Hero Member
Hero Member
Posts: 3068
Joined: 18 Mar 2011, 15:09

Re:How to implement struct

Post by Support Team »

Hello,

There are two ways to handle complex DataTypes in the C++ code.

(1) The DataType is known at compile time
- A C structure and/or a C++ class can be defined in the code
- A type dictionary can be provided on the server side but is not necessary on the client side if the client knows the DataType
- Serializer / deserializer functions for the structure can be registered with the UA stack
- The UA stack is automatically handling the complex Data Type
- Your application code can directly use the C structure / C++ class in the code

(2) The DataType is not known at compile time
In this case there must be generic code that
- is handling the serialization / deserialization of the structure
- is providing the data type dictionary on the server side and is parsing the data type dictionary on the client side


It is possible to implement both options with the current version of the C++ SDK but there are no helper classes / simplifications provided by the SDK at the moment. We can provide sample code for both options on request.

The helper classes / simplifications will be provided by the next major C++ SDK Version 1.4
For option (1) there will be code generation provided through the tool UaModeler.
For option (2) we will provide helper classes

Best Regards,
Unified Automation Support Team
Last edited by Support Team on 07 Feb 2013, 10:48, edited 1 time in total.
Best regards
Unified Automation Support Team

User avatar
Support Team
Hero Member
Hero Member
Posts: 3068
Joined: 18 Mar 2011, 15:09

Re:How to implement struct

Post by Support Team »

Using the current version of the CPP SDK you have to do following steps to provide a known complex structure in the server:
  • Add the data type node to the addressspace

Code: Select all

UaGenericDataType *pDataType = new UaGenericDataType(nodeId, browseName, displayName, description, OpcUa_False);
pTypeNodeConfig->addNodeAndReference(OpcUaId_Structure, pDataType, OpcUaId_HasSubtype);
  
  • Define the encodeable type
    I.e. you have to implement the _Initialize, _Clear, _GetSize, _Encode and _Decode functions. You can use the code for other types in the UA stack file opcua_types.c as example.
  • Register the data type to the stack

Code: Select all

OpcUa_EncodeableType **pTypes = (OpcUa_EncodeableType**)OpcUa_Alloc(2 * sizeof(OpcUa_EncodeableType*));
*(pTypes) = &SampleComplex_EncodeableType;
*(pTypes + 1) = OpcUa_Null;

OpcUa_ProxyStub_AddTypes(pTypes);

OpcUa_Free(pTypes); 
Last edited by Support Team on 07 Feb 2013, 10:48, edited 1 time in total.
Best regards
Unified Automation Support Team

Rajendra
Jr. Member
Jr. Member
Posts: 4
Joined: 27 Jul 2011, 06:50

Re:How to implement struct

Post by Rajendra »

Structure implementation in UA SDK 1.3.1 worked well with the recipe provided on the UaForum. We can now able to see the custom structure on the server side namespace and its value as ExtensionObject.

Now I want to test the server by writing a Client which access the custom structure on the server side. Can any one knows how to get access this structure in the client side (we are not getting any example for the same).

I thought Unified Automation support team probably could give good hints. :)

User avatar
Support Team
Hero Member
Hero Member
Posts: 3068
Joined: 18 Mar 2011, 15:09

Re:How to implement struct

Post by Support Team »

You do the steps 2 und 3 of post 43 for the client, too.

When you read a variable with a complex value you have to do the following things:
1. Check how the data is encoded
2. Check the type of the variable
3. Decode the type

Code: Select all

UaExtensionObject extensionObject;
variant.toExtensionObject(extensionObject);
/*1. Check the encoding*/
switch(extensionObject.encoding())
{
case UaExtensionObject::EncodeableObject:      
    break;
case UaExtensionObject::Binary:
    /*2. Check the data type*/
    if(((OpcUa_ExtensionObject*)(&extensionObject))->TypeId.NodeId.NamespaceIndex == 1)
    {
        switch(((OpcUa_ExtensionObject*)(&extensionObject))->TypeId.NodeId.Identifier.Numeric)
        {
        case YourComplexTypeIdentifier_Encoding_DefaultBinary: //ComplexDataType definition is known by the client
            {
                /*YourComplexType is the struct you have defined for the complex type*/
                YourComplexType complexType;
                decodeYourComplexType(extensionObject, complexType);
            }
        }
    }
}

/*3. Decode*/
void decodeYourComplexType(const UaExtensionObject &extensionObject, YourComplexType &complexType)
{
    OpcUa_MessageContext    cContext;
    OpcUa_StatusCode        uStatus = OpcUa_Good;
    OpcUa_MessageContext_Initialize(&cContext);
    OpcUa_EncodeableObject_ParseExtension(
        (OpcUa_ExtensionObject*)&extensionObject,
        &cContext,
        &Hist_HistogramDataType_EncodeableType,
        (OpcUa_Void**)&complexType);
    OpcUa_MessageContext_Clear(&cContext);
}


Best regards
Unified Automation Support Team

Post Reply