This manual is divided in the following sections:
The OPC UA Stack implements the serialization, security and transport of messages exchanged between different UA Applications. The stack does not contain any application layer functionality. The OPC Foundation is providing different implementations of the stack. The Ansi C version has a platform layer that contains the platform specific code separated from the platform independent functionality.
A SDK simplifies the UA stack APIs, implements common UA functionality needed in most or all UA applications, provides base functionality and helper functions, implements the security handling and provides samples for common use cases.
The Application provides or consumes information via OPC UA. This layer contains the application specific logic and a mapping to OPC UA using the OPC SDKs.
The ANSI C OPC UA Server SDK provides a ANSI C library used to develop OPC UA Servers providing a standard interface to vendor specific systems. The OPC UA Server is normally used to describe the available information from a vendor system and to provide access to the data for external systems in a standard way.
The ANSI C OPC UA SDK is a basic OPC UA SDK designed for embedded devices which provides the basic infrastructure to create an OPC UA Server.
It supports the following OPC UA services:
The C++ way:
// Definition class Foo { public: Foo(); ~Foo(); void doSomething(int x, int y); private: int m_data; }; // Usage Foo *pObject = new Foo(); pObject->doSomething(5, 3); delete pObject;
The ANSI C equivalent:
// Definition struct _Foo { int data; }; typedef struct _Foo Foo; Foo* Foo_Create(); void Foo_Initialize(Foo *pThis); void Foo_DoSomething(Foo *pThis, int x, int y); void Foo_Clear(Foo *pThis); void Foo_Delete(Foo *pThis); // Usage Foo *pObject; pObject = Foo_Create(); Foo_DoSomething(pObject, 5, 3); Foo_Delete(pObject);
ANSI C | C++ equivalent | Description |
---|---|---|
<ClassName>_Create(); | new <ClassName>; | Allocates a new object on the heap and calls the constructor. |
<ClassName>_Initialize(); | <ClassName>::<ClassName>; | The constructor initializes the object. |
<ClassName>_Clear(); | <ClassName>::~<ClassName>; | The destructor cleans up the object. |
<ClassName>_Delete(); | delete ... | Calls the destructor and frees the memory for this object on the heap. |
typedef OpcUa_BaseNode* OpcUa_BaseNodePtr; OpcUa_BaseNodePtr NodeArray[10]; int i; NodeArray[0] = OpcUa_Folder_Create(); NodeArray[1] = OpcUa_DataVariable_Create(); ... for (int i=0; i<10; i++) { NodeTypes type = OpcUa_BaseNode_GetType(NodeArray[i]); // call polymorph GetType function ... OpcUa_BaseNode_Delete(NodeArray[i]); // call polymorph Delete function }
The so called Providers implement application specific nodes using the server infrastructure and connect the server to their underlying IO data. One important Provider that comes with the SDK is the Server Provider. This implements the Server object that is defined by the OPC Foundation and is available in every OPC UA Server.
The interface methods that cross this boundaries are implemented using the macros IFMETHOD and IFMETHODIMP just to simplify coding and to hide OS specific differences. Interface methods have always the return type OpcUa_StatusCode which is also provided by this macros.
#define IFMETHOD(name) typedef OpcUa_StatusCode (OPCUA_DLLCALL *UaServer_pfProvider##name) #define IFMETHODIMP(name) OpcUa_StatusCode OPCUA_DLLCALL name
typedef OpcUa_StatusCode (__stdcall *UaServer_pfProviderCleanup)(); OpcUa_StatusCode __stdcall Cleanup() { return OpcUa_Good; }
typedef OpcUa_StatusCode (*UaServer_pfProviderCleanup)(); OpcUa_StatusCode Cleanup() { return OpcUa_Good; }
All dynamic memory gets allocated through OpcUa_Alloc and is freed using OpcUa_Free which are macros from the OPC UA Stack that call the memory allocation function of the Stack.
Attention: If you decide to link the providers dynamically you also have to link against the OPC UA Stack dynamically to guarantee that there is only one OPC UA Stack with one CRT loaded. This way allocating and freeing memory across dll boundaries works without any problems.
If you link the providers statically you can also link the OPC UA Stack statically.