Typeconversion between Standardtypes and UATypes

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

Moderator: uasdkcpp

Post Reply
AnyOne
Full Member
Full Member
Posts: 9
Joined: 25 Apr 2013, 09:54

Typeconversion between Standardtypes and UATypes

Post by AnyOne »

Dear Support,

I am fairly new to OPC UA and not very experienced in c++ either.
Yet, I am trying to write a function that takes a couple of input arguments and return the corresponding node by NodeID.

Code: Select all

bool readFloat(char nodeId, int nameSpace) 
As I understand in order to read this node I have to put it into an array of "nodesToRead" and get the corresponding value - assuming the Node exists.

Hence I wanted to do

Code: Select all

UaNodeId(nodeId, nameSpace).copyTo(&nodesToRead[i].NodeId)
Now the question that keeps bugging me for quite some hours is:
How can I convert standardtypes into UaTypes?
I tried stuff like

Code: Select all

OpcUa_Int16 ns = setInt16(nameSpace);
UaString node = nodeId.toOpcUaString();
But as you can guess, neither worked and the doc didn't really help me any further, all I found was how to do it the other way round...

I'd really appreciate your help!

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

Re: Typeconversion between Standardtypes and UATypes

Post by Support Team »

Hi

There are several constructors in the UaNodeId class which allow to simply create different kind of NodeIds.
See http://doc.unifiedautomation.com/uasdkc ... odeId.html

Here are a few examples:

Code: Select all

UaNodeId FolderNodeId(OpcUaId_FolderType); // create a numeric nodeid based on the given define in namespace 0 (opcua namespace)
UaNodeId CustomNumericNodeId(17, 2); // creates a numeric nodeid in namespace 2
UANodeId StringNodeId(UaString("Foo"), 3); // creates string nodeid in namespace 3
...
// convert a NodeId into a String for storage
UaString sNodeId = AnyNodeId.toXmlString();
printf("%s\n", sNodeId.toUtf8());
// parse such an XML string when loading a configuration
UaNodeId id = UaNodeId::fromXmlString(sNodeId);
Filling the nodesToRead variable is somewhat more complicated, because the UaReadValueIds class hold a native C array of OpcUa_ReadValueId for performance reasons. So here you have kinda mixture of convenient C++ classes and native C structs from the OPC UA stack.

1.) preallocated the array

Code: Select all

int numVariables = 5;
nodesToRead.create(numVariables)
2.) then fill the elements

Code: Select all

for (int i=0; i<numVariables; i++)
{
    // copy nodeId data of C++ class into C array element
    CurrentNodeId.copyTo(&nodesToRead[i].NodeId);
    nodesToRead[i].AttributeId = OpcUa_Attributes_Value;
    ...
}
// now do the read call
You can find full client examples here:
http://doc.unifiedautomation.com/uasdkc ... lient.html

If you are new to OPC UA you should also read this http://doc.unifiedautomation.com/uasdkc ... ntals.html
You need a basic understanding of NodeIds, Nodes, NodeClasses, References, etc. before you can really use the SDK.

regards,
Unified Automation Support

AnyOne
Full Member
Full Member
Posts: 9
Joined: 25 Apr 2013, 09:54

Re: Typeconversion between Standardtypes and UATypes

Post by AnyOne »

Thank you for the (very fast) helpful answer!
I have flicked through the tutorials beforehand, while some things are explained quite well, others however I didn't find. One of them is typecasting.

So some more questions coming right up:
1) Where is UaNodeId StringNodeId(); declared and documented? The search on the UA website doesn't give any hints. (no matches for StringNodeId) - I assume the last Parameter is an OpcUa_Uint16?
2) Now let's say I want to take my function's int argument as the namespace; How do I convert any proper int to OpcUa_Uint16?

Or would it generally be the better idea to use UaVariant instead and convert using setInt16(...)?

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

Re: Typeconversion between Standardtypes and UATypes

Post by Support Team »

Hi again

StringNodeId is not a function, it is just a variable name that I named to what it contains.

You can also write

Code: Select all

UaNodeId foo(UaString("bla"), 2);
UaNodeId: the class name
foo: the variable name
Depending on the arguments, in this case UaString("bla") and (int)2 it selects automatically the correct constructor of the UaNodeId class (C++ function overloading).
This constructors are described in the link I sent you before.
The string based constructor is exactly described here http://doc.unifiedautomation.com/uasdkc ... d7003de340

OpcUa_Int16 is a typedef to a "short int" on most systems. Because C/C++ don't define fixed size types in portable way the UaStack's platform layer file opcua_p_types.h defines its own types. This can be adapted to every operating system and compiler (portable code).
You can cast (int) to (OpcUa_Int16) and vice versa. This cast is done implicitly like the "2" in the example above.
However when casting a bigger type to smaller one you can loose information so the compiler might show a warning.
In this case an explicit cast tells the compiler that you know what your doing and this loss of information is OK.

Code: Select all

int ns = 3;
UaNodeId foo(UaString("Hello"), (OpcUa_UInt16)ns);
It looks like you don't understand C++ syntax. Maybe you should first try some basic C++ examples. OPC UA is not trivial so you should not learn C++ with OPC UA.
See http://www.cplusplus.com/doc/tutorial/ for some basic examples.
"Effective C++" is great book from Scott Meyers but requires already some basic knowledge: http://www.amazon.com/gp/product/032133 ... 0321334876

AnyOne
Full Member
Full Member
Posts: 9
Joined: 25 Apr 2013, 09:54

Re: Typeconversion between Standardtypes and UATypes

Post by AnyOne »

Hello again,

Well I admit, I am quite out of training concerning C++ and starting again with OPC UA is indeed a bitter pill to swallow since a lot of linkers and custom data types are involved.

From your answer I misinterpreted there was a StringNodeId(...) - my bad. My typecast didn't work for another (very trivial) reason.

Anyway the problem was solved. Thank you

Post Reply