C++ SDK
The C++ SDK provides transport layers and message routing with an observer/subscriber pattern.
Installation
Full SDK (with network transports)
python -m struct_frame messages.proto --build_cpp --cpp_path generated/ --sdkIncludes ASIO for UDP, TCP, Serial, and WebSocket transports.
Embedded SDK (no external dependencies)
python -m struct_frame messages.proto --build_cpp --cpp_path generated/ --sdk_embeddedMinimal footprint for embedded systems. Serial transport only.
Observer Pattern
Subscribe to messages using function pointers or lambdas:
#include "struct_frame_sdk/sdk_embedded.hpp"#include "messages.structframe.hpp"
void handle_status(const StatusMessage& msg, uint8_t msgId) { std::cout << "Status: " << msg.value << std::endl;}
int main() { // Create SDK with transport and message-info callback. // The only template argument is the frame profile config. StructFrame::StructFrameSdkT<StructFrame::ProfileStandardConfig> sdk(&my_transport, &get_message_info);
// Subscribe to messages by message ID sdk.subscribe<StatusMessage>(StatusMessage::MSG_ID, handle_status);
// Connect the transport (incoming data is handled via callbacks) sdk.Connect();}FrameMsgInfo Subscription And Forwarding
You can subscribe to every complete parsed frame directly as FrameMsgInfo:
StructFrame::StructFrameSdkT<StructFrame::ProfileStandardConfig> sdk(&transport, &get_message_info);
auto all_frames = sdk.subscribeFrameInfo( [](const StructFrame::FrameMsgInfo& frame) { // Complete frame metadata is available even for CRC-failed frames. std::cout << "msg_id=" << frame.msg_id << " len=" << frame.msg_len << " valid=" << frame.valid << std::endl; });To bridge two SDKs, use one of two forwarding modes:
SendDirect(frame_info)for same-profile forwarding (most efficient, no re-encode)Send(frame_info)for cross-profile forwarding (re-encodes for destination profile)
Most efficient same-profile bridge:
StructFrame::StructFrameSdkT<StructFrame::ProfileStandardConfig> source_sdk(&transport_a, &get_message_info);
StructFrame::StructFrameSdkT<StructFrame::ProfileStandardConfig> target_sdk(&transport_b, &get_message_info);
auto forward = source_sdk.subscribeFrameInfo( [&](const StructFrame::FrameMsgInfo& frame) { target_sdk.SendDirect(frame); // fastest: forwards original frame bytes });
// Encode once on source side and inject/send as neededStatusMessage msg{};msg.value = 42;
uint8_t wire[512];size_t wire_len = StructFrame::FrameEncoderWithCrc<StructFrame::ProfileStandardConfig>::encode( wire, sizeof(wire), msg);
// Feed encoded bytes into source SDK parse path:source_sdk.Feed(wire, wire_len);Cross-profile bridge (re-encode on destination):
auto forward_cross_profile = source_sdk.subscribeFrameInfo( [&](const StructFrame::FrameMsgInfo& frame) { target_sdk.Send(frame); // profile-aware re-encode });Use the same type for other profiles by changing only the config:
StructFrame::StructFrameSdkT<StructFrame::ProfileSensorConfig> sensor_sdk(&transport, &get_message_info);
StructFrame::StructFrameSdkT<StructFrame::ProfileIPCConfig> ipc_sdk(&transport, &get_message_info);
StructFrame::StructFrameSdkT<StructFrame::ProfileBulkConfig> bulk_sdk(&transport, &get_message_info);Transports (Full SDK)
Serial
#include "struct_frame_sdk/serial_transport.hpp"
// SerialTransport requires a platform-specific ISerialPort implementation.// Provide your own class that implements the ISerialPort interface// (open, close, write, read, is_open methods).StructFrame::SerialTransportConfig config;StructFrame::SerialTransport serial(&my_serial_port, config);serial.connect();Network (UDP, TCP, WebSocket)
#include "struct_frame_sdk/network_transports.hpp"
// UDPStructFrame::UdpTransportConfig udp_config{.remoteHost = "192.168.1.100", .remotePort = 8080};StructFrame::UdpTransport udp(udp_config);udp.connect();
// TCPStructFrame::TcpTransportConfig tcp_config{.host = "192.168.1.100", .port = 8080};StructFrame::TcpTransport tcp(tcp_config);tcp.connect();Frame Profiles
Use predefined frame profiles:
#include "frame_profiles.hpp"
using namespace FrameParsers;
// Standard profile (recommended)uint8_t buffer[1024];ProfileStandardWriter writer(buffer, sizeof(buffer));ProfileStandardAccumulatingReader reader;
// Sensor profile (minimal overhead)ProfileSensorWriter sensor_writer(buffer, sizeof(buffer));ProfileSensorAccumulatingReader sensor_reader(get_message_info);See Framing Details for more profiles.