Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions rclcpp/include/rclcpp/typesupport_helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <tuple>

#include "rcpputils/shared_library.hpp"
#include "rosidl_runtime_cpp/action_type_support_decl.hpp"
#include "rosidl_runtime_cpp/message_type_support_decl.hpp"
#include "rosidl_runtime_cpp/service_type_support_decl.hpp"

Expand Down Expand Up @@ -72,6 +73,24 @@ get_service_typesupport_handle(
const std::string & typesupport_identifier,
rcpputils::SharedLibrary & library);

/// Extract the action type support handle from the library.
/**
* The library needs to match the action type. The shared library must stay loaded for the lifetime
* of the result.
*
* \param[in] type The action type, e.g. "example_interfaces/action/Fibonacci"
* \param[in] typesupport_identifier Type support identifier, typically "rosidl_typesupport_cpp"
* \param[in] library The shared type support library
* \throws std::runtime_error if the symbol of type not found in the library.
* \return A action type support handle
*/
RCLCPP_PUBLIC
const rosidl_action_type_support_t *
get_action_typesupport_handle(
const std::string & type,
const std::string & typesupport_identifier,
rcpputils::SharedLibrary & library);

} // namespace rclcpp

#endif // RCLCPP__TYPESUPPORT_HELPERS_HPP_
15 changes: 15 additions & 0 deletions rclcpp/src/rclcpp/typesupport_helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,4 +177,19 @@ const rosidl_service_type_support_t * get_service_typesupport_handle(
));
}

const rosidl_action_type_support_t * get_action_typesupport_handle(
const std::string & type,
const std::string & typesupport_identifier,
rcpputils::SharedLibrary & library)
{
static const std::string typesupport_name = "action";
static const std::string symbol_part_name = "__get_action_type_support_handle__";
static const std::string middle_module_additional = "action";

return static_cast<const rosidl_action_type_support_t *>(get_typesupport_handle_impl(
type, typesupport_identifier, typesupport_name, symbol_part_name,
middle_module_additional, library
));
}

} // namespace rclcpp
40 changes: 37 additions & 3 deletions rclcpp/test/rclcpp/test_typesupport_helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,21 +106,55 @@ TEST(TypesupportHelpersTest, returns_service_type_info_for_valid_library) {
}
}

TEST(TypesupportHelpersTest, returns_action_type_info_for_valid_legacy_library) {
try {
auto library = rclcpp::get_typesupport_library(
"test_msgs/NestedMessage", "rosidl_typesupport_cpp");
auto nestedmessage_typesupport = rclcpp::get_action_typesupport_handle(
"test_msgs/NestedMessage", "rosidl_typesupport_cpp", *library);

EXPECT_THAT(
std::string(nestedmessage_typesupport->goal_service_type_support->typesupport_identifier),
ContainsRegex("rosidl_typesupport"));
} catch (const std::runtime_error & e) {
FAIL() << e.what();
}
}

TEST(TypesupportHelpersTest, returns_action_type_info_for_valid_library) {
try {
auto library = rclcpp::get_typesupport_library(
"test_msgs/action/NestedMessage", "rosidl_typesupport_cpp");
auto nestedmessage_typesupport = rclcpp::get_action_typesupport_handle(
"test_msgs/action/NestedMessage", "rosidl_typesupport_cpp", *library);

EXPECT_THAT(
std::string(nestedmessage_typesupport->goal_service_type_support->typesupport_identifier),
ContainsRegex("rosidl_typesupport"));
} catch (const std::runtime_error & e) {
FAIL() << e.what();
}
}

TEST(TypesupportHelpersTest, test_throw_exception_with_invalid_type) {
// message
std::string invalid_type = "test_msgs/msg/InvalidType";
auto library = rclcpp::get_typesupport_library(invalid_type, "rosidl_typesupport_cpp");
EXPECT_THROW(
rclcpp::get_message_typesupport_handle(invalid_type, "rosidl_typesupport_cpp", *library),
std::runtime_error);
EXPECT_THROW(
rclcpp::get_service_typesupport_handle(invalid_type, "rosidl_typesupport_cpp", *library),
std::runtime_error);

// service
invalid_type = "test_msgs/srv/InvalidType";
library = rclcpp::get_typesupport_library(invalid_type, "rosidl_typesupport_cpp");
EXPECT_THROW(
rclcpp::get_service_typesupport_handle(invalid_type, "rosidl_typesupport_cpp", *library),
std::runtime_error);

// action
invalid_type = "test_msgs/action/InvalidType";
library = rclcpp::get_typesupport_library(invalid_type, "rosidl_typesupport_cpp");
EXPECT_THROW(
rclcpp::get_action_typesupport_handle(invalid_type, "rosidl_typesupport_cpp", *library),
std::runtime_error);
}