open62541pp 0.19.0
C++ wrapper of open62541
Loading...
Searching...
No Matches
open62541pp

open62541pp

License: MPL 2.0 CI Compatibility Package Documentation Coverage

C++ wrapper of the amazing open62541 OPC UA library.

Open source and free implementation licensed under the Mozilla Public License v2.0.
📖 Documentation • 📝 Examples

🎯 Features and goals

The latest stable open62541 release is integrated as a submodule. Depending on the value of the CMake flag UAPP_INTERNAL_OPEN62541, the submodule or an external open62541 installation is used. All open62541 releases since v1.0 are supported and tested in a CI pipeline with debug/release builds and as static/dynamic library.

The project is currently in beta stage but already used in production. Version v1.0.0 is planned for 2025. No major breaking changes are expected.

While in v0.x.x, breaking changes may occur in minor releases. This projects follows the two-version deprecation path: when a feature is marked as deprecated in v0.x.0, it may be removed as early as v0.(x+2).0. Deprecated APIs are declared with the [[deprecated]] attribute and noted in the changelog.

📝 Examples

Explore all examples in the examples/ directory.

Server

int main() {
opcua::Server server;
// Add a variable node to the Objects node
opcua::Node parentNode{server, opcua::ObjectId::ObjectsFolder};
opcua::Node myIntegerNode = parentNode.addVariable({1, 1000}, "TheAnswer");
// Write value attribute
myIntegerNode.writeValue(opcua::Variant{42});
server.run();
}
High-level node class to access node attribute, browse and populate address space.
Definition node.hpp:45
Node & writeValue(const Variant &value)
Write the AttributeId::Value attribute of a node.
Definition node.hpp:1155
Node addVariable(const NodeId &id, std::string_view browseName, const VariableAttributes &attributes={}, const NodeId &variableType=VariableTypeId::BaseDataVariableType, const NodeId &referenceType=ReferenceTypeId::HasComponent)
Add variable.
Definition node.hpp:156
High-level server class.
Definition server.hpp:142
void run()
Run the server's main loop. This method will block until Server::stop is called.
UA_Variant wrapper class.
Definition types.hpp:1048

Client

#include <iostream>
int main() {
opcua::Client client;
client.connect("opc.tcp://localhost:4840");
opcua::Node node{client, opcua::VariableId::Server_ServerStatus_CurrentTime};
const auto dt = node.readValue().to<opcua::DateTime>();
std::cout << "Server date (UTC): " << dt.format("%Y-%m-%d %H:%M:%S") << std::endl;
}
High-level client class.
Definition client.hpp:130
void connect(std::string_view endpointUrl)
Connect to the selected server.
UA_DateTime wrapper class.
Definition types.hpp:381
String format(std::string_view format, bool localtime=false) const
Convert to string with given format (same format codes as strftime).

⇆ Type conversion

Type conversion from and to native UA_* types are handled by the opcua::TypeConverter struct. Have a look at the typeconversion example.

Compile-time checks are used where possible:

// ✅ will compile
int number = 5;
var.assign(&number);
// ❌ won't compile, because std::string can't be assigned without copy (conversion needed)
std::string str{"test"};
var.assign(&str);
// ✅ will compile
var.assign(str);
void assign(std::nullptr_t ptr) noexcept=delete

You can add template specializations to add conversions for arbitrary types:

namespace opcua {
template <>
struct TypeConverter<std::byte> {
using NativeType = UA_Byte;
[[nodiscard]] static std::byte fromNative(const UA_Byte& src) { /* ... */ }
[[nodiscard]] static UA_Byte toNative(const std::byte& src) { /* ... */ }
};
} // namespace opcua
uint8_t UA_Byte

Type map of built-in types

Type Type open62541 Typedef Wrapper Conversions
Boolean UA_Boolean bool
SByte UA_SByte int8_t
Byte UA_Byte uint8_t
Int16 UA_Int16 int16_t
UInt16 UA_UInt16 uint16_t
Int32 UA_Int32 int32_t
UInt32 UA_UInt32 uint32_t
Int64 UA_Int64 int64_t
UInt64 UA_UInt64 uint64_t
Float UA_Float float
Double UA_Double double
String UA_String opcua::String std::string, std::string_view, const char*, char[N]
DateTime UA_DateTime int64_t opcua::DateTime std::chrono::time_point
Guid UA_Guid opcua::Guid
ByteString UA_ByteString UA_String opcua::ByteString
XmlElement UA_XmlElement UA_String opcua::XmlElement
NodeId UA_NodeId opcua::NodeId
ExpandedNodeId UA_ExpandedNodeId opcua::ExpandedNodeId
StatusCode UA_StatusCode uint32_t opcua::StatusCode
QualifiedName UA_QualifiedName opcua::QualifiedName
LocalizedText UA_LocalizedText opcua::LocalizedText
ExtensionObject UA_ExtensionObject opcua::ExtensionObject
DataValue UA_DataValue opcua::DataValue
Variant UA_Variant opcua::Variant
DiagnosticInfo UA_DiagnosticInfo opcua::DiagnosticInfo

🚀 Getting started

The library can be built, integrated and installed using CMake.

Please check out the open62541 build options here: https://www.open62541.org/doc/1.3/building.html#build-options

Open62541pp provides additional build options:

  • UAPP_INTERNAL_OPEN62541: Use internal open62541 library if ON or search for installed open62541 library if OFF
  • UAPP_ENABLE_NODESETLOADER: Enable nodeset loader to load NodeSet2.xml files at runtime
  • UAPP_BUILD_DOCUMENTATION: Build documentation
  • UAPP_BUILD_EXAMPLES: Build examples for examples directory
  • UAPP_BUILD_TESTS: Build unit tests
  • UAPP_ENABLE_COVERAGE: Enable coverage analysis
  • UAPP_ENABLE_CLANG_TIDY: Enable static code analysis with Clang-Tidy
  • UAPP_ENABLE_SANITIZER_ADDRESS/LEAK/UNDEFINED/THREAD: Enable sanitizers

Integrate as an embedded (in-source) dependency

Add it to your project as a Git submodule (git submodule add https://github.com/open62541pp/open62541pp.git) and link it with CMake:

add_subdirectory(extern/open62541pp) # the submodule directory
target_link_libraries(myexecutable PRIVATE open62541pp::open62541pp)

Integrate as a pre-compiled library

If you build and install this package to your system, a open62541ppConfig.cmake file will be generated and installed to your system. The installed library can be found and linked within CMake:

find_package(open62541pp CONFIG REQUIRED)
target_link_libraries(myexecutable PRIVATE open62541pp::open62541pp)

Integrate via package managers

The library is available through the following package managers:

  • vcpkg: Please refer to the vcpkg documentation how to use it within your project. You can easily use vcpkg to build and install open62541pp:

    vcpkg install open62541pp

Build and install

# clone repository
git clone --recursive https://github.com/open62541pp/open62541pp.git
cd open62541pp
# build
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DUAPP_BUILD_EXAMPLES=ON -DUAPP_BUILD_TESTS=ON ..
cmake --build . # single-configuration generator like Make or Ninja
cmake --build . --config Release # multi-configuration generator like Visual Studio, Xcode
# run tests
ctest --output-on-failure
# install to system
cmake --install .

Dependencies

  • open62541 as integrated submodule or external dependency
  • catch2 for tests

🤝 Contribute

Contributions and feature requests are very welcome. Please have a look at the contribution guidelines.