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
How to implement struct
Moderator: uasdkcpp
-
- Hero Member
- Posts: 25
- Joined: 14 Oct 2008, 12:55
How to implement struct
Last edited by Lafond on 07 Feb 2013, 10:48, edited 1 time in total.
- Support Team
- Hero Member
- Posts: 3072
- Joined: 18 Mar 2011, 15:09
Re:How to implement struct
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
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
Unified Automation Support Team
- Support Team
- Hero Member
- Posts: 3072
- Joined: 18 Mar 2011, 15:09
Re:How to implement struct
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
Unified Automation Support Team
-
- Jr. Member
- Posts: 4
- Joined: 27 Jul 2011, 06:50
Re:How to implement struct
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.
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.
- Support Team
- Hero Member
- Posts: 3072
- Joined: 18 Mar 2011, 15:09
Re:How to implement struct
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
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
Unified Automation Support Team