Hello World en C++
Ce tutoriel couvre la construction de l'application de capteur de temperature en utilisant le C++17 moderne avec HDDS.
Duree : ~10 minutes Prerequis : Bibliotheque C++ HDDS installee
Etape 1 : Creer le fichier IDL
Creez Temperature.idl :
module sensors {
@topic
struct Temperature {
@key string sensor_id;
float value;
unsigned long long timestamp;
};
};
Etape 2 : Generer le code C++
hdds-gen -l cpp Temperature.idl
Cela genere :
Temperature.hpp- Definitions de types avec des fonctionnalites C++ modernesTemperature.cpp- Implementation de la serialisation
Etape 3 : Creer le Publisher
Creez publisher.cpp :
#include <iostream>
#include <chrono>
#include <thread>
#include <hdds/hdds.hpp>
#include "Temperature.hpp"
using namespace std::chrono_literals;
int main() {
std::cout << "Starting temperature publisher..." << std::endl;
try {
// 1. Create DomainParticipant
hdds::DomainParticipant participant(0);
std::cout << "Joined domain 0" << std::endl;
// 2. Create Topic
auto topic = participant.create_topic<sensors::Temperature>("temperature/room1");
std::cout << "Created topic: temperature/room1" << std::endl;
// 3. Create Publisher and DataWriter
auto publisher = participant.create_publisher();
auto writer = publisher.create_writer(topic);
std::cout << "DataWriter created, waiting for subscribers..." << std::endl;
// 4. Wait for subscribers
writer.wait_for_subscribers(1, 30s);
std::cout << "Subscriber connected!" << std::endl;
// 5. Publish temperature readings
for (int i = 0; i < 10; ++i) {
sensors::Temperature temp;
temp.sensor_id = "sensor-001";
temp.value = 22.0f + (i * 0.5f);
temp.timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()
).count();
writer.write(temp);
std::cout << "Published: sensor=" << temp.sensor_id
<< ", temp=" << temp.value << "C" << std::endl;
std::this_thread::sleep_for(1s);
}
std::cout << "Publisher finished" << std::endl;
} catch (const hdds::Exception& e) {
std::cerr << "HDDS Error: " << e.what() << std::endl;
return 1;
}
return 0;
}
Etape 4 : Creer le Subscriber
Creez subscriber.cpp :
#include <iostream>
#include <chrono>
#include <hdds/hdds.hpp>
#include "Temperature.hpp"
using namespace std::chrono_literals;
int main() {
std::cout << "Starting temperature subscriber..." << std::endl;
try {
// 1. Create DomainParticipant
hdds::DomainParticipant participant(0);
std::cout << "Joined domain 0" << std::endl;
// 2. Create Topic
auto topic = participant.create_topic<sensors::Temperature>("temperature/room1");
std::cout << "Created topic: temperature/room1" << std::endl;
// 3. Create Subscriber and DataReader
auto subscriber = participant.create_subscriber();
auto reader = subscriber.create_reader(topic);
std::cout << "DataReader created, waiting for data..." << std::endl;
// 4. Read samples in a loop
while (true) {
if (reader.wait_for_data(5s)) {
// Take all available samples
for (auto& sample : reader.take()) {
std::cout << "Received: sensor=" << sample.data().sensor_id
<< ", temp=" << sample.data().value << "C"
<< ", time=" << sample.data().timestamp << std::endl;
}
} else {
std::cout << "No data received in 5 seconds, waiting..." << std::endl;
}
}
} catch (const hdds::Exception& e) {
std::cerr << "HDDS Error: " << e.what() << std::endl;
return 1;
}
return 0;
}
Etape 5 : Creer le CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(hdds-hello-world CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(hdds REQUIRED)
# Generate type support
hdds_generate_cpp(GENERATED_SRCS Temperature.idl)
# Publisher
add_executable(publisher publisher.cpp ${GENERATED_SRCS})
target_link_libraries(publisher PRIVATE hdds::hdds-cpp)
# Subscriber
add_executable(subscriber subscriber.cpp ${GENERATED_SRCS})
target_link_libraries(subscriber PRIVATE hdds::hdds-cpp)
Etape 6 : Compiler et executer
mkdir build && cd build
cmake ..
cmake --build .
# Terminal 1
./subscriber
# Terminal 2
./publisher
Fonctionnalites C++ modernes
Iteration range-based
for (auto& sample : reader.take()) {
if (sample.info().valid_data) {
process(sample.data());
}
}
Callbacks Lambda
reader.on_data_available([](auto& reader) {
for (auto& sample : reader.take()) {
std::cout << "Received: " << sample.data().value << std::endl;
}
});
Async/Await (C++20)
#include <hdds/hdds_async.hpp>
hdds::task<void> run_subscriber() {
hdds::DomainParticipant participant(0);
auto topic = participant.create_topic<sensors::Temperature>("temperature/room1");
auto reader = participant.create_subscriber().create_reader(topic);
while (true) {
auto samples = co_await reader.take_async();
for (auto& sample : samples) {
std::cout << "Received: " << sample.data().value << std::endl;
}
}
}
Gestion des ressources RAII
Tous les objets C++ HDDS utilisent le RAII. Aucun nettoyage manuel necessaire :
{
hdds::DomainParticipant participant(0);
auto writer = participant.create_publisher()
.create_writer(topic);
writer.write(data);
} // Everything cleaned up automatically
Configuration QoS
// Reliable with history
auto writer_qos = hdds::DataWriterQos()
.reliability(hdds::Reliability::Reliable(1s))
.history(hdds::History::KeepLast(10))
.durability(hdds::Durability::TransientLocal);
auto writer = publisher.create_writer(topic, writer_qos);
Prochaines etapes
- Hello World Python - Version Python
- API Reference C++ - Documentation C++ complete