sysrepo-cpp are object-oriented bindings of the sysrepo library. It uses RAII for automatic memory management.
- sysrepo - the
develbranch (even for themasterbranch of sysrepo-cpp) - libyang-cpp - C++ bindings for libyang
- C++20 compiler (e.g., GCC 10.x+, clang 10+)
- CMake 3.19+
- optionally for built-in tests, Doctest as a C++ unit test framework
- optionally for built-in tests, trompeloeil for mock objects in C++
- optionally for the docs, Doxygen
sysrepo-cpp uses CMake for building. The standard way of building sysrepo-cpp looks like this:
mkdir build cd build cmake .. make make install - Most of the classes in sysrepo-cpp are not directly instantiated by the user, and are instead returned by methods. The only class directly instantiated by the user is the
sysrepo::Connectionclass. - The classes are no longer wrapped by
std::shared_ptr. However, they are still copyable and one can have multiple instances of, i.e.,sysrepo::Sessionthat refer to the same session. Memory management will still work automatically.
The core classes for sysrepo-cpp are sysrepo::Connection and sysrepo::Session. Creating those is straightforward.
auto session = sysrepo::Connection{}.sessionStart();These are some of the most typical operations supported by sysrepo-cpp.
auto session = sysrepo::Connection{}.sessionStart(); session.setItem("/module:myCont/myLeaf", "some-value"); session.applyChanges(); if (auto data = session.getData("/module:myCont/myLeaf")) { // `data` points to "/module:myCont", to get the leaf, we need to use findPath auto leaf = data.findPath("/module:myCont/myLeaf"); std::cout << leaf->asTerm().valueStr() << "\n"; } else { std::cout << "no data\n"; }Note: sysrepo::Session::getData always returns the first top-level node of the data that corresponds to the XPath you provided. You might need to use the findPath method on data to get the actual node you wanted.
sysrepo::ModuleChangeCb moduleChangeCb = [] (auto session, auto, auto, auto, auto, auto) { for (const auto& change : session.getChanges()) { // do stuff } return sysrepo::ErrorCode::Ok; }; auto session = sysrepo::Connection{}.sessionStart(); auto sub = sess.onModuleChange("my-module-name", moduleChangeCb); sub.onRPCAction(...);In C++, one usually wants to create a class that groups all of the sysrepo-cpp classes, mainly sessions and subscriptions. Here is an example of such class:
class SysrepoManager { public: SysrepoManager() : m_sess(sysrepo::Connection{}.sessionStart()) , m_sub(/*???*/) // How to initialize this? { } private: sysrepo::Session m_sess; sysrepo::Subscription m_sub; };The example illustrates a small caveat of the sysrepo::Subscription class: it is not possible to have an "empty" instance of it. Every sysrepo::Subscription instance must already point to a valid subscription. There are two ways of solving this:
- Just initialize the
m_subfield in the member initializer list. This works if one wants to immediately subscribe to something on the creation of the example class. - If actual empty subscriptions are needed
std::optional<sysrepo::Subscription>can be used as the type ofm_sub. This enables having no active subscriptions, however, when actually creating subscriptions, the first call must usem_sessand any following should use them_sub. Example:m_sub = m_sess.onModuleChange(...); m_sub.onRPCAction(...); m_sub.onModuleChange(...);
For more examples, check out the examples/ and the tests/ directory.
The development is being done on Gerrit here. Instructions on how to submit patches can be found here. GitHub Pull Requests are not used.