16 #include "rclcpp/typesupport_helpers.hpp"
26 #include "ament_index_cpp/get_package_prefix.hpp"
27 #include "ament_index_cpp/get_resources.hpp"
28 #include "rcpputils/shared_library.hpp"
29 #include "rcpputils/find_library.hpp"
30 #include "rosidl_runtime_cpp/message_type_support_decl.hpp"
39 std::string get_typesupport_library_path(
40 const std::string & package_name,
const std::string & typesupport_identifier)
42 const char * dynamic_library_folder;
44 dynamic_library_folder =
"/bin/";
46 dynamic_library_folder =
"/lib/";
48 dynamic_library_folder =
"/lib/";
51 std::string package_prefix;
53 package_prefix = ament_index_cpp::get_package_prefix(package_name);
54 }
catch (ament_index_cpp::PackageNotFoundError & e) {
55 throw std::runtime_error(e.what());
58 const std::string library_path = rcpputils::path_for_library(
59 package_prefix + dynamic_library_folder,
60 package_name +
"__" + typesupport_identifier);
61 if (library_path.empty()) {
62 throw std::runtime_error(
63 "Typesupport library for " + package_name +
" does not exist in '" + package_prefix +
69 std::tuple<std::string, std::string, std::string>
70 extract_type_identifier(
const std::string & full_type)
72 char type_separator =
'/';
73 auto sep_position_back = full_type.find_last_of(type_separator);
74 auto sep_position_front = full_type.find_first_of(type_separator);
75 if (sep_position_back == std::string::npos ||
76 sep_position_back == 0 ||
77 sep_position_back == full_type.length() - 1)
79 throw std::runtime_error(
80 "Message type is not of the form package/type and cannot be processed");
83 std::string package_name = full_type.substr(0, sep_position_front);
84 std::string middle_module =
"";
85 if (sep_position_back - sep_position_front > 0) {
87 full_type.substr(sep_position_front + 1, sep_position_back - sep_position_front - 1);
89 std::string type_name = full_type.substr(sep_position_back + 1);
91 return std::make_tuple(package_name, middle_module, type_name);
96 std::shared_ptr<rcpputils::SharedLibrary>
99 auto package_name = std::get<0>(extract_type_identifier(type));
100 auto library_path = get_typesupport_library_path(package_name, typesupport_identifier);
101 return std::make_shared<rcpputils::SharedLibrary>(library_path);
104 const rosidl_message_type_support_t *
106 const std::string & type,
107 const std::string & typesupport_identifier,
108 rcpputils::SharedLibrary & library)
110 std::string package_name;
111 std::string middle_module;
112 std::string type_name;
113 std::tie(package_name, middle_module, type_name) = extract_type_identifier(type);
115 auto mk_error = [&package_name, &type_name](
auto reason) {
116 std::stringstream rcutils_dynamic_loading_error;
117 rcutils_dynamic_loading_error <<
118 "Something went wrong loading the typesupport library for message type " << package_name <<
119 "/" << type_name <<
". " << reason;
120 return rcutils_dynamic_loading_error.str();
124 std::string symbol_name = typesupport_identifier +
"__get_message_type_support_handle__" +
125 package_name +
"__" + (middle_module.empty() ?
"msg" : middle_module) +
"__" + type_name;
127 const rosidl_message_type_support_t * (* get_ts)() =
nullptr;
129 get_ts =
reinterpret_cast<decltype(get_ts)
>(library.get_symbol(symbol_name));
131 }
catch (std::runtime_error &) {
132 throw std::runtime_error{mk_error(
"Library could not be found.")};
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
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_typesupport_handle(const std::string &type, const std::string &typesupport_identifier, rcpputils::SharedLibrary &library)
Extract the type support handle from the library.