16 #include "rclcpp/typesupport_helpers.hpp"
28 #include "ament_index_cpp/get_package_prefix.hpp"
29 #include "ament_index_cpp/get_resources.hpp"
30 #include "rcpputils/shared_library.hpp"
31 #include "rcpputils/find_library.hpp"
32 #include "rosidl_runtime_cpp/message_type_support_decl.hpp"
40 const void * get_typesupport_handle_impl(
41 const std::string & type,
42 const std::string & typesupport_identifier,
43 const std::string & typesupport_name,
44 const std::string & symbol_part_name,
45 const std::string & middle_module_additional,
46 rcpputils::SharedLibrary & library)
48 std::string package_name;
49 std::string middle_module;
50 std::string type_name;
53 if (middle_module.empty()) {
54 middle_module = middle_module_additional;
57 auto mk_error = [&package_name, &type_name, &typesupport_name](
auto reason) {
58 std::stringstream rcutils_dynamic_loading_error;
59 rcutils_dynamic_loading_error <<
60 "Something went wrong loading the typesupport library for " <<
61 typesupport_name <<
" type " << package_name <<
62 "/" << type_name <<
". " << reason;
63 return rcutils_dynamic_loading_error.str();
67 std::string symbol_name = typesupport_identifier + symbol_part_name +
68 package_name +
"__" + middle_module +
"__" + type_name;
69 const void * (* get_ts)() =
nullptr;
71 get_ts =
reinterpret_cast<decltype(get_ts)
>(library.get_symbol(symbol_name));
73 }
catch (std::runtime_error &) {
74 throw std::runtime_error{mk_error(
"Library could not be found.")};
79 std::string string_trim(std::string_view str_v)
81 auto begin = std::find_if_not(str_v.begin(), str_v.end(), [](
unsigned char ch) {
82 return std::isspace(ch);
84 auto end = std::find_if_not(str_v.rbegin(), str_v.rend(), [](
unsigned char ch) {
85 return std::isspace(ch);
90 return std::string(begin, end);
95 std::tuple<std::string, std::string, std::string>
98 char type_separator =
'/';
99 auto sep_position_back = full_type.find_last_of(type_separator);
100 auto sep_position_front = full_type.find_first_of(type_separator);
101 if (sep_position_back == std::string::npos ||
102 sep_position_front == 0 ||
103 sep_position_back == 0 ||
104 sep_position_back == full_type.length() - 1)
106 throw std::runtime_error(
107 "Message type is not of the form package/type and cannot be processed");
110 std::string package_name = full_type.substr(0, sep_position_front);
111 std::string middle_module =
"";
112 if (sep_position_back - sep_position_front > 0) {
114 full_type.substr(sep_position_front + 1, sep_position_back - sep_position_front - 1);
116 std::string type_name = full_type.substr(sep_position_back + 1);
118 return std::make_tuple(
119 string_trim(package_name), string_trim(middle_module), string_trim(type_name));
123 const std::string & package_name,
const std::string & typesupport_identifier)
125 const char * dynamic_library_folder;
127 dynamic_library_folder =
"bin";
129 dynamic_library_folder =
"lib";
131 dynamic_library_folder =
"lib";
134 std::filesystem::path package_prefix;
136 ament_index_cpp::get_package_prefix(package_name, package_prefix);
137 }
catch (ament_index_cpp::PackageNotFoundError & e) {
138 throw std::runtime_error(e.what());
141 const std::string library_path = rcpputils::path_for_library(
142 (package_prefix / dynamic_library_folder).
string(),
143 package_name +
"__" + typesupport_identifier);
144 if (library_path.empty()) {
145 throw std::runtime_error(
146 "Typesupport library for " + package_name +
" does not exist in '" +
147 package_prefix.string() +
"'.");
152 std::shared_ptr<rcpputils::SharedLibrary>
157 return std::make_shared<rcpputils::SharedLibrary>(library_path);
161 const std::string & type,
162 const std::string & typesupport_identifier,
163 rcpputils::SharedLibrary & library)
165 static const std::string typesupport_name =
"message";
166 static const std::string symbol_part_name =
"__get_message_type_support_handle__";
167 static const std::string middle_module_additional =
"msg";
169 return static_cast<const rosidl_message_type_support_t *
>(get_typesupport_handle_impl(
170 type, typesupport_identifier, typesupport_name, symbol_part_name,
171 middle_module_additional, library
176 const std::string & type,
177 const std::string & typesupport_identifier,
178 rcpputils::SharedLibrary & library)
180 static const std::string typesupport_name =
"service";
181 static const std::string symbol_part_name =
"__get_service_type_support_handle__";
182 static const std::string middle_module_additional =
"srv";
184 return static_cast<const rosidl_service_type_support_t *
>(get_typesupport_handle_impl(
185 type, typesupport_identifier, typesupport_name, symbol_part_name,
186 middle_module_additional, library
191 const std::string & type,
192 const std::string & typesupport_identifier,
193 rcpputils::SharedLibrary & library)
195 static const std::string typesupport_name =
"action";
196 static const std::string symbol_part_name =
"__get_action_type_support_handle__";
197 static const std::string middle_module_additional =
"action";
199 return static_cast<const rosidl_action_type_support_t *
>(get_typesupport_handle_impl(
200 type, typesupport_identifier, typesupport_name, symbol_part_name,
201 middle_module_additional, library
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
RCLCPP_PUBLIC std::string get_typesupport_library_path(const std::string &package_name, const std::string &typesupport_identifier)
Look for the library in the ament prefix paths and return the path to the type support library.
RCLCPP_PUBLIC std::shared_ptr< rcpputils::SharedLibrary > get_typesupport_library(const std::string &type, const std::string &typesupport_identifier)
Load the type support library for the given type.
RCLCPP_PUBLIC const rosidl_message_type_support_t * get_message_typesupport_handle(const std::string &type, const std::string &typesupport_identifier, rcpputils::SharedLibrary &library)
Extracts the message type support handle from the library.
RCLCPP_PUBLIC const rosidl_service_type_support_t * get_service_typesupport_handle(const std::string &type, const std::string &typesupport_identifier, rcpputils::SharedLibrary &library)
Extracts the service type support handle from the library.
RCLCPP_PUBLIC const rosidl_action_type_support_t * get_action_typesupport_handle(const std::string &type, const std::string &typesupport_identifier, rcpputils::SharedLibrary &library)
Extracts the action type support handle from the library.
RCLCPP_PUBLIC std::tuple< std::string, std::string, std::string > extract_type_identifier(const std::string &full_type)
Extract the package name, middle module, and type name from a full type string.