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.