├── .gitignore ├── rosidl_typesupport_c ├── test │ ├── msg │ │ └── Test.msg │ ├── test_cli_extension.py │ ├── test_type_support.c │ ├── benchmark │ │ └── benchmark_type_support_dispatch.cpp │ ├── test_message_type_support_dispatch.cpp │ └── test_service_type_support_dispatch.cpp ├── setup.cfg ├── README.md ├── src │ ├── identifier.c │ ├── message_type_support_dispatch.cpp │ ├── service_type_support_dispatch.cpp │ └── type_support_dispatch.hpp ├── bin │ └── rosidl_typesupport_c ├── docs │ └── FEATURES.md ├── include │ └── rosidl_typesupport_c │ │ ├── identifier.h │ │ ├── message_type_support_dispatch.h │ │ ├── service_type_support_dispatch.h │ │ ├── type_support_map.h │ │ └── visibility_control.h ├── Doxyfile ├── rosidl_typesupport_c │ ├── __init__.py │ └── cli.py ├── rosidl_typesupport_c-extras.cmake.in ├── package.xml ├── cmake │ ├── get_used_typesupports.cmake │ └── rosidl_typesupport_c_generate_interfaces.cmake ├── resource │ ├── idl__type_support.cpp.em │ ├── action__type_support.c.em │ ├── msg__type_support.cpp.em │ └── srv__type_support.cpp.em ├── CMakeLists.txt └── QUALITY_DECLARATION.md ├── rosidl_typesupport_cpp ├── test │ ├── msg │ │ └── Test.msg │ ├── test_cli_extension.py │ ├── test_type_support.cpp │ ├── benchmark │ │ └── benchmark_type_support_dispatch.cpp │ ├── test_service_type_support_dispatch.cpp │ └── test_message_type_support_dispatch.cpp ├── setup.cfg ├── README.md ├── bin │ └── rosidl_typesupport_cpp ├── docs │ └── FEATURES.md ├── src │ ├── identifier.cpp │ ├── message_type_support_dispatch.cpp │ ├── service_type_support_dispatch.cpp │ └── type_support_dispatch.hpp ├── include │ └── rosidl_typesupport_cpp │ │ ├── identifier.hpp │ │ ├── message_type_support_dispatch.hpp │ │ ├── service_type_support_dispatch.hpp │ │ └── visibility_control.h ├── Doxyfile ├── rosidl_typesupport_cpp │ ├── __init__.py │ └── cli.py ├── rosidl_typesupport_cpp-extras.cmake.in ├── package.xml ├── resource │ ├── idl__type_support.cpp.em │ ├── action__type_support.cpp.em │ ├── msg__type_support.cpp.em │ └── srv__type_support.cpp.em ├── CMakeLists.txt ├── cmake │ └── rosidl_typesupport_cpp_generate_interfaces.cmake └── QUALITY_DECLARATION.md ├── .clang-format ├── README.md ├── CONTRIBUTING.md └── rosidl_typesupport_tests ├── package.xml ├── CMakeLists.txt ├── CHANGELOG.rst └── test ├── rosidl_typesupport_cpp └── test_service_typesupport.cpp └── rosidl_typesupport_c └── test_service_typesupport.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | *.pyc 3 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/test/msg/Test.msg: -------------------------------------------------------------------------------- 1 | string test 2 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/test/msg/Test.msg: -------------------------------------------------------------------------------- 1 | string test 2 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/setup.cfg: -------------------------------------------------------------------------------- 1 | [options.entry_points] 2 | rosidl_cli.command.generate.typesupport_extensions = 3 | c = rosidl_typesupport_c.cli:GenerateCTypesupport 4 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/setup.cfg: -------------------------------------------------------------------------------- 1 | [options.entry_points] 2 | rosidl_cli.command.generate.typesupport_extensions = 3 | cpp = rosidl_typesupport_cpp.cli:GenerateCppTypesupport 4 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: Google 2 | IndentWidth: 2 3 | BreakBeforeBraces: Linux 4 | AllowShortIfStatementsOnASingleLine: false 5 | IndentCaseLabels: false 6 | PointerAlignment: Middle 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rosidl_typesupport 2 | 3 | For more information about each package, see their package-level READMEs. 4 | 5 | * [rosidl_typesupport_c](rosidl_typesupport_c/README.md) 6 | * [rosidl_typesupport_cpp](rosidl_typesupport_cpp/README.md) 7 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/README.md: -------------------------------------------------------------------------------- 1 | # rosidl_typesupport_c 2 | 3 | `rosidl_typesupport_c` provides functionality for getting the associated message or service c typesupport handler functions. 4 | 5 | ## Features 6 | 7 | The features provided by `rosidl_typesupport_c` are described in [FEATURES](docs/FEATURES.md). 8 | 9 | ## Quality Declaration 10 | 11 | This package claims to be in the **Quality Level 1** category, see the [Quality Declaration](./QUALITY_DECLARATION.md) for more details. 12 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/README.md: -------------------------------------------------------------------------------- 1 | # rosidl_typesupport_cpp 2 | 3 | `rosidl_typesupport_cpp` provides functionality for getting the associated message or service c++ typesupport handler functions. 4 | 5 | ## Features 6 | 7 | The features provided by `rosidl_typesupport_cpp` are described in [FEATURES](docs/FEATURES.md). 8 | 9 | ## Quality Declaration 10 | 11 | This package claims to be in the **Quality Level 1** category, see the [Quality Declaration](./QUALITY_DECLARATION.md) for more details. 12 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/src/identifier.c: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | ROSIDL_TYPESUPPORT_C_EXPORT 18 | const char * rosidl_typesupport_c__typesupport_identifier = "rosidl_typesupport_c"; 19 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/bin/rosidl_typesupport_c: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import argparse 4 | import sys 5 | 6 | from rosidl_typesupport_c import generate_c 7 | 8 | 9 | def main(argv=sys.argv[1:]): 10 | parser = argparse.ArgumentParser( 11 | description='Generate the C type support to handle ROS messages.', 12 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 13 | parser.add_argument( 14 | '--generator-arguments-file', 15 | required=True, 16 | help='The location of the file containing the generator arguments') 17 | parser.add_argument( 18 | '--typesupports', 19 | required=True, 20 | nargs='+', 21 | help='The typesupports to be used') 22 | args = parser.parse_args(argv) 23 | 24 | generate_c(args.generator_arguments_file, args.typesupports) 25 | 26 | 27 | if __name__ == '__main__': 28 | sys.exit(main()) 29 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/bin/rosidl_typesupport_cpp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import argparse 4 | import sys 5 | 6 | from rosidl_typesupport_cpp import generate_cpp 7 | 8 | 9 | def main(argv=sys.argv[1:]): 10 | parser = argparse.ArgumentParser( 11 | description='Generate the C++ type support to handle ROS messages.', 12 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 13 | parser.add_argument( 14 | '--generator-arguments-file', 15 | required=True, 16 | help='The location of the file containing the generator arguments') 17 | parser.add_argument( 18 | '--typesupports', 19 | required=True, 20 | nargs='+', 21 | help='The typesupports to be used') 22 | args = parser.parse_args(argv) 23 | 24 | generate_cpp(args.generator_arguments_file, args.typesupports) 25 | 26 | 27 | if __name__ == '__main__': 28 | sys.exit(main()) 29 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/docs/FEATURES.md: -------------------------------------------------------------------------------- 1 | # rosidl_typesupport_cpp features 2 | 3 | `rosidl_typesupport_cpp` provides a Python generator executable, `rosidl_typesupport_cpp`, based on Empy to create rosidl C++ source files. 4 | 5 | The templates utilized by this generator executable are located in the `resource` directory and generate source files for messages, services and actions. 6 | 7 | `rosidl_typesupport_cpp` defines a typesupport identifier, which is declared in `identifier.hpp`. 8 | 9 | `rosidl_typesupport_cpp` provides the following functionality for incorporation into generated typesupport source files. 10 | 11 | * `message_type_support_dispatch.hpp`: Look up message type support handle functions from available libraries. 12 | * `service_type_support_dispatch.hpp`: Look up service type support handle functions from available libraries. 13 | * `type_support_map_t.hpp`: This defines the lookup of C++ typesupport handlers. 14 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/src/identifier.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | namespace rosidl_typesupport_cpp 18 | { 19 | 20 | ROSIDL_TYPESUPPORT_CPP_EXPORT 21 | const char * typesupport_identifier = "rosidl_typesupport_cpp"; 22 | 23 | } // namespace rosidl_typesupport_cpp 24 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Any contribution that you make to this repository will 2 | be under the Apache 2 License, as dictated by that 3 | [license](http://www.apache.org/licenses/LICENSE-2.0.html): 4 | 5 | ~~~ 6 | 5. Submission of Contributions. Unless You explicitly state otherwise, 7 | any Contribution intentionally submitted for inclusion in the Work 8 | by You to the Licensor shall be under the terms and conditions of 9 | this License, without any additional terms or conditions. 10 | Notwithstanding the above, nothing herein shall supersede or modify 11 | the terms of any separate license agreement you may have executed 12 | with Licensor regarding such Contributions. 13 | ~~~ 14 | 15 | Contributors must sign-off each commit by adding a `Signed-off-by: ...` 16 | line to commit messages to certify that they have the right to submit 17 | the code they are contributing to the project according to the 18 | [Developer Certificate of Origin (DCO)](https://developercertificate.org/). 19 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/docs/FEATURES.md: -------------------------------------------------------------------------------- 1 | # rosidl_typesupport_c features 2 | 3 | `rosidl_typesupport_c` provides a Python generator executable, `rosidl_typesupport_c`, based on Empy to create rosidl C source files. 4 | 5 | The templates utilized by this generator executable are located in the `resource` directory and generate source files for messages, services and actions. 6 | 7 | The generator also generates a visibility_control header based on https://gcc.gnu.org/wiki/Visibility. 8 | 9 | `rosidl_typesupport_c` defines a typesupport identifier, which is declared in `identifier.h`. 10 | 11 | `rosidl_typesupport_c` provides the following functionality for incorporation into generated typesupport source files. 12 | 13 | * `message_type_support_dispatch.h`: Look up message type support handle functions from available libraries. 14 | * `service_type_support_dispatch.h`: Look up service type support handle functions from available libraries. 15 | * `type_support_map_t.h`: This defines the lookup of C typesupport handlers. 16 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/include/rosidl_typesupport_cpp/identifier.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef ROSIDL_TYPESUPPORT_CPP__IDENTIFIER_HPP_ 16 | #define ROSIDL_TYPESUPPORT_CPP__IDENTIFIER_HPP_ 17 | 18 | #include "rosidl_typesupport_cpp/visibility_control.h" 19 | 20 | namespace rosidl_typesupport_cpp 21 | { 22 | 23 | /// String identifier specific to rosidl_typesupport_cpp. 24 | ROSIDL_TYPESUPPORT_CPP_IMPORT 25 | extern const char * typesupport_identifier; 26 | 27 | } // namespace rosidl_typesupport_cpp 28 | 29 | #endif // ROSIDL_TYPESUPPORT_CPP__IDENTIFIER_HPP_ 30 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/include/rosidl_typesupport_c/identifier.h: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef ROSIDL_TYPESUPPORT_C__IDENTIFIER_H_ 16 | #define ROSIDL_TYPESUPPORT_C__IDENTIFIER_H_ 17 | 18 | #include "rosidl_typesupport_c/visibility_control.h" 19 | 20 | #ifdef __cplusplus 21 | extern "C" 22 | { 23 | #endif 24 | 25 | /// String identifier specific to rosidl_typesupport_c. 26 | ROSIDL_TYPESUPPORT_C_PUBLIC 27 | extern const char * rosidl_typesupport_c__typesupport_identifier; 28 | 29 | #ifdef __cplusplus 30 | } 31 | #endif 32 | 33 | #endif // ROSIDL_TYPESUPPORT_C__IDENTIFIER_H_ 34 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/src/message_type_support_dispatch.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "rosidl_typesupport_cpp/message_type_support_dispatch.hpp" 16 | 17 | #include "type_support_dispatch.hpp" 18 | 19 | namespace rosidl_typesupport_cpp 20 | { 21 | 22 | const rosidl_message_type_support_t * 23 | get_message_typesupport_handle_function( 24 | const rosidl_message_type_support_t * handle, const char * identifier) noexcept 25 | { 26 | return rosidl_typesupport_cpp::get_typesupport_handle_function< 27 | rosidl_message_type_support_t>(handle, identifier); 28 | } 29 | 30 | } // namespace rosidl_typesupport_cpp 31 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/src/service_type_support_dispatch.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "rosidl_typesupport_cpp/service_type_support_dispatch.hpp" 16 | 17 | #include "type_support_dispatch.hpp" 18 | 19 | namespace rosidl_typesupport_cpp 20 | { 21 | 22 | const rosidl_service_type_support_t * 23 | get_service_typesupport_handle_function( 24 | const rosidl_service_type_support_t * handle, const char * identifier) noexcept 25 | { 26 | return rosidl_typesupport_cpp::get_typesupport_handle_function< 27 | rosidl_service_type_support_t>(handle, identifier); 28 | } 29 | 30 | } // namespace rosidl_typesupport_cpp 31 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/Doxyfile: -------------------------------------------------------------------------------- 1 | # All settings not listed here will use the Doxygen default values. 2 | 3 | PROJECT_NAME = "rosidl_typesupport_c" 4 | PROJECT_NUMBER = master 5 | PROJECT_BRIEF = "ROSIDL C Typesupport" 6 | 7 | # Use these lines to include the generated logging.hpp (update install path if needed) 8 | INPUT = README.md ./include ./docs ./QUALITY_DECLARATION.md 9 | USE_MDFILE_AS_MAINPAGE = README.md 10 | 11 | RECURSIVE = YES 12 | OUTPUT_DIRECTORY = doc_output 13 | 14 | EXTRACT_ALL = YES 15 | SORT_MEMBER_DOCS = NO 16 | 17 | GENERATE_LATEX = NO 18 | 19 | ENABLE_PREPROCESSING = YES 20 | MACRO_EXPANSION = YES 21 | EXPAND_ONLY_PREDEF = YES 22 | PREDEFINED = ROSIDL_TYPESUPPORT_C_PUBLIC= 23 | 24 | # Tag files that do not exist will produce a warning and cross-project linking will not work. 25 | TAGFILES += "../../../../doxygen_tag_files/cppreference-doxygen-web.tag.xml=http://en.cppreference.com/w/" 26 | TAGFILES += "../../../../doxygen_tag_files/rosidl_runtime_c.tag=http://docs.ros2.org/latest/api/rosidl_runtime_c/" 27 | # Uncomment to generate tag files for cross-project linking. 28 | #GENERATE_TAGFILE = "../../../../doxygen_tag_files/rosidl_typesupport_c.tag" 29 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/src/message_type_support_dispatch.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "rosidl_typesupport_c/message_type_support_dispatch.h" 16 | 17 | #include "type_support_dispatch.hpp" 18 | 19 | #ifdef __cplusplus 20 | extern "C" 21 | { 22 | #endif 23 | 24 | const rosidl_message_type_support_t * 25 | rosidl_typesupport_c__get_message_typesupport_handle_function( 26 | const rosidl_message_type_support_t * handle, const char * identifier) 27 | { 28 | return rosidl_typesupport_c::get_typesupport_handle_function< 29 | rosidl_message_type_support_t>(handle, identifier); 30 | } 31 | 32 | #ifdef __cplusplus 33 | } 34 | #endif 35 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/src/service_type_support_dispatch.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "rosidl_typesupport_c/service_type_support_dispatch.h" 16 | 17 | #include "type_support_dispatch.hpp" 18 | 19 | #ifdef __cplusplus 20 | extern "C" 21 | { 22 | #endif 23 | 24 | const rosidl_service_type_support_t * 25 | rosidl_typesupport_c__get_service_typesupport_handle_function( 26 | const rosidl_service_type_support_t * handle, const char * identifier) 27 | { 28 | return rosidl_typesupport_c::get_typesupport_handle_function< 29 | rosidl_service_type_support_t>(handle, identifier); 30 | } 31 | 32 | #ifdef __cplusplus 33 | } 34 | #endif 35 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/Doxyfile: -------------------------------------------------------------------------------- 1 | # All settings not listed here will use the Doxygen default values. 2 | 3 | PROJECT_NAME = "rosidl_typesupport_cpp" 4 | PROJECT_NUMBER = master 5 | PROJECT_BRIEF = "ROSIDL C++ Typesupport" 6 | 7 | # Use these lines to include the generated logging.hpp (update install path if needed) 8 | INPUT = README.md ./include ./docs ./QUALITY_DECLARATION.md 9 | USE_MDFILE_AS_MAINPAGE = README.md 10 | 11 | RECURSIVE = YES 12 | OUTPUT_DIRECTORY = doc_output 13 | 14 | EXTRACT_ALL = YES 15 | SORT_MEMBER_DOCS = NO 16 | 17 | GENERATE_LATEX = NO 18 | 19 | ENABLE_PREPROCESSING = YES 20 | MACRO_EXPANSION = YES 21 | EXPAND_ONLY_PREDEF = YES 22 | PREDEFINED = ROSIDL_TYPESUPPORT_CPP_PUBLIC= 23 | 24 | # Tag files that do not exist will produce a warning and cross-project linking will not work. 25 | TAGFILES += "../../../../doxygen_tag_files/cppreference-doxygen-web.tag.xml=http://en.cppreference.com/w/" 26 | TAGFILES += "../../../../doxygen_tag_files/rosidl_runtime_c.tag=http://docs.ros2.org/latest/api/rosidl_runtime_c/" 27 | # Uncomment to generate tag files for cross-project linking. 28 | #GENERATE_TAGFILE = "../../../../doxygen_tag_files/rosidl_typesupport_cpp.tag" 29 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/rosidl_typesupport_c/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016-2018 Open Source Robotics Foundation, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from rosidl_pycommon import generate_files 16 | 17 | 18 | def generate_c(generator_arguments_file, type_supports): 19 | """ 20 | Generate the C type support to handle ROS messages. 21 | 22 | :param generator_arguments_file: Path location of the file containing the generator arguments 23 | :param type_support: List of type supports to be used 24 | """ 25 | mapping = { 26 | 'idl__type_support.cpp.em': '%s__type_support.cpp', 27 | } 28 | return generate_files( 29 | generator_arguments_file, mapping, 30 | additional_context={'type_supports': type_supports}) 31 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/rosidl_typesupport_cpp/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016-2018 Open Source Robotics Foundation, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from rosidl_pycommon import generate_files 16 | 17 | 18 | def generate_cpp(generator_arguments_file, type_supports): 19 | """ 20 | Generate the c++ type support to handle ROS messages. 21 | 22 | :param generator_arguments_file: Path location of the file containing the generator arguments 23 | :param type_support: List of type supports to be used 24 | """ 25 | mapping = { 26 | 'idl__type_support.cpp.em': '%s__type_support.cpp', 27 | } 28 | return generate_files( 29 | generator_arguments_file, mapping, 30 | additional_context={'type_supports': type_supports}) 31 | -------------------------------------------------------------------------------- /rosidl_typesupport_tests/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | rosidl_typesupport_tests 5 | 3.4.1 6 | Test rosidl_typesupport_c and rosidl_typesupport_cpp packages 7 | Jacob Perron 8 | Apache License 2.0 9 | Brian Chen 10 | 11 | ament_cmake 12 | 13 | action_msgs 14 | ament_lint_auto 15 | ament_lint_common 16 | ament_cmake_gtest 17 | rcutils 18 | rmw 19 | rmw_implementation 20 | rosidl_cmake 21 | rosidl_generator_cpp 22 | rosidl_typesupport_c 23 | rosidl_typesupport_cpp 24 | service_msgs 25 | test_interface_files 26 | 27 | 28 | ament_cmake 29 | 30 | 31 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/rosidl_typesupport_c-extras.cmake.in: -------------------------------------------------------------------------------- 1 | # generated from 2 | # rosidl_typesupport_c/rosidl_typesupport_c-extras.cmake.in 3 | 4 | # use the same type of library 5 | set(rosidl_typesupport_c_LIBRARY_TYPE "@rosidl_typesupport_c_LIBRARY_TYPE@") 6 | 7 | include("${rosidl_typesupport_c_DIR}/get_used_typesupports.cmake") 8 | get_used_typesupports(_typesupports "rosidl_typesupport_c") 9 | 10 | # Make sure extension points are registered in order 11 | find_package(rosidl_generator_c QUIET) 12 | foreach(_typesupport ${_typesupports}) 13 | find_package(${_typesupport} QUIET) 14 | endforeach() 15 | 16 | find_package(ament_cmake_core QUIET REQUIRED) 17 | ament_register_extension( 18 | "rosidl_generate_idl_interfaces" 19 | "rosidl_typesupport_c" 20 | "rosidl_typesupport_c_generate_interfaces.cmake") 21 | 22 | set(rosidl_typesupport_c_BIN 23 | "${rosidl_typesupport_c_DIR}/../../../lib/rosidl_typesupport_c/rosidl_typesupport_c") 24 | normalize_path(rosidl_typesupport_c_BIN 25 | "${rosidl_typesupport_c_BIN}") 26 | 27 | set(rosidl_typesupport_c_GENERATOR_FILES 28 | "${rosidl_typesupport_c_DIR}/../../../@PYTHON_INSTALL_DIR@/rosidl_typesupport_c/__init__.py") 29 | normalize_path(rosidl_typesupport_c_GENERATOR_FILES 30 | "${rosidl_typesupport_c_GENERATOR_FILES}") 31 | 32 | set(rosidl_typesupport_c_TEMPLATE_DIR 33 | "${rosidl_typesupport_c_DIR}/../resource") 34 | normalize_path(rosidl_typesupport_c_TEMPLATE_DIR 35 | "${rosidl_typesupport_c_TEMPLATE_DIR}") 36 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/rosidl_typesupport_cpp-extras.cmake.in: -------------------------------------------------------------------------------- 1 | # generated from 2 | # rosidl_typesupport_cpp/rosidl_typesupport_cpp-extras.cmake.in 3 | 4 | # use the same type of library 5 | set(rosidl_typesupport_cpp_LIBRARY_TYPE "@rosidl_typesupport_cpp_LIBRARY_TYPE@") 6 | 7 | find_package(rosidl_typesupport_c QUIET REQUIRED) 8 | get_used_typesupports(_typesupports "rosidl_typesupport_cpp") 9 | 10 | # Make sure extension points are registered in order 11 | find_package(rosidl_generator_cpp QUIET) 12 | foreach(_typesupport ${_typesupports}) 13 | find_package(${_typesupport} QUIET) 14 | endforeach() 15 | 16 | find_package(ament_cmake_core QUIET REQUIRED) 17 | ament_register_extension( 18 | "rosidl_generate_idl_interfaces" 19 | "rosidl_typesupport_cpp" 20 | "rosidl_typesupport_cpp_generate_interfaces.cmake") 21 | 22 | set(rosidl_typesupport_cpp_BIN 23 | "${rosidl_typesupport_cpp_DIR}/../../../lib/rosidl_typesupport_cpp/rosidl_typesupport_cpp") 24 | normalize_path(rosidl_typesupport_cpp_BIN 25 | "${rosidl_typesupport_cpp_BIN}") 26 | 27 | set(rosidl_typesupport_cpp_GENERATOR_FILES 28 | "${rosidl_typesupport_cpp_DIR}/../../../@PYTHON_INSTALL_DIR@/rosidl_typesupport_cpp/__init__.py") 29 | normalize_path(rosidl_typesupport_cpp_GENERATOR_FILES 30 | "${rosidl_typesupport_cpp_GENERATOR_FILES}") 31 | 32 | set(rosidl_typesupport_cpp_TEMPLATE_DIR 33 | "${rosidl_typesupport_cpp_DIR}/../resource") 34 | normalize_path(rosidl_typesupport_cpp_TEMPLATE_DIR 35 | "${rosidl_typesupport_cpp_TEMPLATE_DIR}") 36 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/include/rosidl_typesupport_c/message_type_support_dispatch.h: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef ROSIDL_TYPESUPPORT_C__MESSAGE_TYPE_SUPPORT_DISPATCH_H_ 16 | #define ROSIDL_TYPESUPPORT_C__MESSAGE_TYPE_SUPPORT_DISPATCH_H_ 17 | 18 | #include "rosidl_runtime_c/message_type_support_struct.h" 19 | 20 | #include "rosidl_typesupport_c/visibility_control.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" 24 | { 25 | #endif 26 | 27 | /// Get the message type support handle specific to this identifier. 28 | /** 29 | * If the identifier is the same as this handle's typesupport_identifier, then the handle is 30 | * simply returned, otherwise it's loaded from a shared library. 31 | * 32 | * \param handle Handle to message type support 33 | * \param identifier The typesupport identifier to get the handle function for 34 | * \return The associated message typesupport handle if found, otherwise NULL 35 | */ 36 | ROSIDL_TYPESUPPORT_C_PUBLIC 37 | const rosidl_message_type_support_t * 38 | rosidl_typesupport_c__get_message_typesupport_handle_function( 39 | const rosidl_message_type_support_t * handle, const char * identifier); 40 | 41 | #ifdef __cplusplus 42 | } 43 | #endif 44 | 45 | #endif // ROSIDL_TYPESUPPORT_C__MESSAGE_TYPE_SUPPORT_DISPATCH_H_ 46 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/include/rosidl_typesupport_c/service_type_support_dispatch.h: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef ROSIDL_TYPESUPPORT_C__SERVICE_TYPE_SUPPORT_DISPATCH_H_ 16 | #define ROSIDL_TYPESUPPORT_C__SERVICE_TYPE_SUPPORT_DISPATCH_H_ 17 | 18 | #include "rosidl_runtime_c/service_type_support_struct.h" 19 | 20 | #include "rosidl_typesupport_c/visibility_control.h" 21 | 22 | #ifdef __cplusplus 23 | extern "C" 24 | { 25 | #endif 26 | 27 | /// Get the service type support handle specific to this identifier. 28 | /** 29 | * If the identifier is the same as this handle's typesupport_identifier, then the handle is 30 | * simply returned, otherwise it's loaded from a shared library. 31 | * 32 | * \param handle Handle to message type support 33 | * \param identifier The typesupport identifier to get the handle function for 34 | * \return The associated service typesupport handle if found, otherwise NULL 35 | */ 36 | ROSIDL_TYPESUPPORT_C_PUBLIC 37 | const rosidl_service_type_support_t * 38 | rosidl_typesupport_c__get_service_typesupport_handle_function( 39 | const rosidl_service_type_support_t * handle, const char * identifier); 40 | 41 | #ifdef __cplusplus 42 | } 43 | #endif 44 | 45 | #endif // ROSIDL_TYPESUPPORT_C__SERVICE_TYPE_SUPPORT_DISPATCH_H_ 46 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/include/rosidl_typesupport_c/type_support_map.h: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef ROSIDL_TYPESUPPORT_C__TYPE_SUPPORT_MAP_H_ 16 | #define ROSIDL_TYPESUPPORT_C__TYPE_SUPPORT_MAP_H_ 17 | 18 | #include 19 | 20 | #ifdef __cplusplus 21 | extern "C" 22 | { 23 | #endif 24 | 25 | /// Contains all available C typesupport handles to choose from. 26 | typedef struct type_support_map_t 27 | { 28 | // TODO(dirk-thomas) const should not be defined for the fields 29 | // but should be set for the struct when it is being used 30 | // same for rosidl_message_type_support_t et al 31 | 32 | /// Length of the `typesupport_identifier`, `symbol_name` and `data` arrays. 33 | const size_t size; 34 | 35 | /// The ROS 2 package this is generated from. 36 | const char * package_name; 37 | 38 | /// Array of identifiers for the type_supports. 39 | const char * const * typesupport_identifier; 40 | 41 | /// Array of symbol names to get the typesupports. 42 | const char * const * symbol_name; 43 | 44 | /// Array of pointers to type support handle functions that were successfully found. 45 | void ** data; 46 | } type_support_map_t; 47 | 48 | #ifdef __cplusplus 49 | } 50 | #endif 51 | 52 | #endif // ROSIDL_TYPESUPPORT_C__TYPE_SUPPORT_MAP_H_ 53 | -------------------------------------------------------------------------------- /rosidl_typesupport_tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.20) 2 | project(rosidl_typesupport_tests) 3 | 4 | # Default to C++17 5 | if(NOT CMAKE_CXX_STANDARD) 6 | set(CMAKE_CXX_STANDARD 17) 7 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 8 | endif() 9 | 10 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 11 | add_compile_options(-Wall -Wextra -Wpedantic) 12 | endif() 13 | 14 | find_package(ament_cmake REQUIRED) 15 | 16 | if(BUILD_TESTING) 17 | find_package(ament_cmake_gtest REQUIRED) 18 | find_package(ament_lint_auto REQUIRED) 19 | find_package(rcutils REQUIRED) 20 | find_package(rmw REQUIRED) 21 | find_package(rmw_implementation REQUIRED) 22 | find_package(rosidl_cmake REQUIRED) 23 | find_package(rosidl_generator_cpp REQUIRED) 24 | find_package(test_interface_files REQUIRED) 25 | 26 | ament_lint_auto_find_test_dependencies() 27 | 28 | rosidl_generate_interfaces(${PROJECT_NAME} 29 | ${test_interface_files_MSG_FILES} 30 | ${test_interface_files_SRV_FILES} 31 | ${test_interface_files_ACTION_FILES} 32 | SKIP_INSTALL 33 | ) 34 | 35 | rosidl_get_typesupport_target(cpp_typesupport_target ${PROJECT_NAME} "rosidl_typesupport_cpp") 36 | rosidl_get_typesupport_target(c_typesupport_target ${PROJECT_NAME} "rosidl_typesupport_c") 37 | 38 | ament_add_gtest(test_service_typesupport_cpp 39 | test/rosidl_typesupport_cpp/test_service_typesupport.cpp 40 | ) 41 | target_link_libraries(test_service_typesupport_cpp 42 | "${cpp_typesupport_target}" 43 | rmw::rmw 44 | rmw_implementation::rmw_implementation 45 | ) 46 | 47 | ament_add_gtest(test_service_typesupport_c 48 | test/rosidl_typesupport_c/test_service_typesupport.cpp 49 | ) 50 | target_link_libraries(test_service_typesupport_c 51 | "${c_typesupport_target}" 52 | rmw::rmw 53 | rmw_implementation::rmw_implementation 54 | ) 55 | endif() 56 | 57 | ament_package() 58 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/include/rosidl_typesupport_cpp/message_type_support_dispatch.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef ROSIDL_TYPESUPPORT_CPP__MESSAGE_TYPE_SUPPORT_DISPATCH_HPP_ 16 | #define ROSIDL_TYPESUPPORT_CPP__MESSAGE_TYPE_SUPPORT_DISPATCH_HPP_ 17 | 18 | #include "rosidl_runtime_c/message_type_support_struct.h" 19 | #include "rosidl_runtime_c/visibility_control.h" 20 | 21 | #include "rosidl_typesupport_cpp/visibility_control.h" 22 | 23 | namespace rosidl_typesupport_cpp 24 | { 25 | 26 | /// Get the message type support handle specific to this identifier. 27 | /** 28 | * If the identifier is the same as this handle's typesupport_identifier, then the handle is 29 | * simply returned, otherwise it's loaded from a shared library. 30 | * 31 | * \param handle Handle to message type support 32 | * \param identifier The typesupport identifier to get the handle function for 33 | * \return The associated message typesupport handle if found, otherwise NULL 34 | */ 35 | ROSIDL_TYPESUPPORT_CPP_PUBLIC 36 | const rosidl_message_type_support_t * 37 | get_message_typesupport_handle_function( 38 | const rosidl_message_type_support_t * handle, const char * identifier) noexcept; 39 | 40 | } // namespace rosidl_typesupport_cpp 41 | 42 | #endif // ROSIDL_TYPESUPPORT_CPP__MESSAGE_TYPE_SUPPORT_DISPATCH_HPP_ 43 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/include/rosidl_typesupport_cpp/service_type_support_dispatch.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef ROSIDL_TYPESUPPORT_CPP__SERVICE_TYPE_SUPPORT_DISPATCH_HPP_ 16 | #define ROSIDL_TYPESUPPORT_CPP__SERVICE_TYPE_SUPPORT_DISPATCH_HPP_ 17 | 18 | #include "rosidl_runtime_c/service_type_support_struct.h" 19 | #include "rosidl_runtime_c/visibility_control.h" 20 | 21 | #include "rosidl_typesupport_cpp/visibility_control.h" 22 | 23 | namespace rosidl_typesupport_cpp 24 | { 25 | 26 | /// Get the service type support handle specific to this identifier. 27 | /** 28 | * If the identifier is the same as this handle's typesupport_identifier, then the handle is 29 | * simply returned, otherwise it's loaded from a shared library. 30 | * 31 | * \param handle Handle to message type support 32 | * \param identifier The typesupport identifier to get the handle function for 33 | * \return The associated service typesupport handle if found, otherwise NULL 34 | */ 35 | ROSIDL_TYPESUPPORT_CPP_PUBLIC 36 | const rosidl_service_type_support_t * 37 | get_service_typesupport_handle_function( 38 | const rosidl_service_type_support_t * handle, const char * identifier) noexcept; 39 | 40 | } // namespace rosidl_typesupport_cpp 41 | 42 | #endif // ROSIDL_TYPESUPPORT_CPP__SERVICE_TYPE_SUPPORT_DISPATCH_HPP_ 43 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/test/test_cli_extension.py: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Open Source Robotics Foundation, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import pathlib 16 | 17 | from ament_index_python import get_resources 18 | from rosidl_cli.command.generate.api import generate 19 | 20 | TEST_DIR = str(pathlib.Path(__file__).parent) 21 | 22 | 23 | def test_cli_extension_for_smoke(tmp_path, capsys): 24 | # NOTE(hidmic): pytest and empy do not play along, 25 | # the latter expects some proxy will stay in sys.stdout 26 | # and the former insists in overwriting it 27 | interface_files = [TEST_DIR + ':msg/Test.msg'] 28 | 29 | with capsys.disabled(): # so do everything in one run 30 | # Passing target typesupport implementations explictly 31 | ts = 'c[typesupport_implementations:{}]'.format( 32 | list(get_resources('rosidl_typesupport_c')) 33 | ) 34 | generate( 35 | package_name='rosidl_typesupport_c', 36 | interface_files=interface_files, 37 | typesupports=[ts], 38 | output_path=tmp_path / 'explicit_args' 39 | ) 40 | 41 | # Using default typesupport implementations 42 | generate( 43 | package_name='rosidl_typesupport_c', 44 | interface_files=interface_files, 45 | typesupports=['c'], 46 | output_path=tmp_path / 'defaults' 47 | ) 48 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/test/test_cli_extension.py: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Open Source Robotics Foundation, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import pathlib 16 | 17 | from ament_index_python import get_resources 18 | from rosidl_cli.command.generate.api import generate 19 | 20 | TEST_DIR = str(pathlib.Path(__file__).parent) 21 | 22 | 23 | def test_cli_extension_for_smoke(tmp_path, capsys): 24 | # NOTE(hidmic): pytest and empy do not play along, 25 | # the latter expects some proxy will stay in sys.stdout 26 | # and the former insists in overwriting it 27 | interface_files = [TEST_DIR + ':msg/Test.msg'] 28 | 29 | with capsys.disabled(): # so do everything in one run 30 | # Passing target typesupport implementations explictly 31 | ts = 'cpp[typesupport_implementations:{}]'.format( 32 | list(get_resources('rosidl_typesupport_cpp')) 33 | ) 34 | generate( 35 | package_name='rosidl_typesupport_cpp', 36 | interface_files=interface_files, 37 | typesupports=[ts], 38 | output_path=tmp_path / 'explicit_args' 39 | ) 40 | 41 | # Using default typesupport implementations 42 | generate( 43 | package_name='rosidl_typesupport_cpp', 44 | interface_files=interface_files, 45 | typesupports=['cpp'], 46 | output_path=tmp_path / 'defaults' 47 | ) 48 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/test/test_type_support.c: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Provide a symbol so they can be checked with get_typesupport_handle_function() 16 | 17 | #include "rosidl_runtime_c/message_type_support_struct.h" 18 | #include "rosidl_runtime_c/service_type_support_struct.h" 19 | #include "rosidl_typesupport_c/visibility_control.h" 20 | 21 | // If ROSIDL_TYPESUPPORT_C_PUBLIC is used, it selects dllimport instead of dllexport, but the 22 | // function still needs to be defined separately. Windows has gotten picky with its compiler 23 | // warnings recently. 24 | #if defined _WIN32 || defined __CYGWIN__ 25 | __declspec(dllexport) const rosidl_message_type_support_t * test_message_type_support(void); 26 | __declspec(dllexport) const rosidl_service_type_support_t * test_service_type_support(void); 27 | #else 28 | const rosidl_message_type_support_t * test_message_type_support(void); 29 | const rosidl_service_type_support_t * test_service_type_support(void); 30 | #endif 31 | 32 | static const rosidl_message_type_support_t message_type_support = { 33 | 0, 0, 0, 0, 0, 0 34 | }; 35 | 36 | static const rosidl_service_type_support_t service_type_support = { 37 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 38 | }; 39 | 40 | const rosidl_message_type_support_t * test_message_type_support(void) 41 | { 42 | return &message_type_support; 43 | } 44 | 45 | const rosidl_service_type_support_t * test_service_type_support(void) 46 | { 47 | return &service_type_support; 48 | } 49 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | rosidl_typesupport_c 5 | 3.4.1 6 | Generate the type support for C messages. 7 | 8 | Dharini Dutia 9 | Shane Loretz 10 | 11 | Apache License 2.0 12 | 13 | Chris Lalancette 14 | Dirk Thomas 15 | 16 | ament_cmake_ros_core 17 | 18 | python3 19 | 20 | rcpputils 21 | rcutils 22 | 23 | rosidl_runtime_c 24 | 25 | 26 | rosidl_typesupport_introspection_c 27 | 28 | ament_cmake_core 29 | rosidl_runtime_c 30 | 31 | ament_index_python 32 | rosidl_cli 33 | rosidl_generator_c 34 | rosidl_pycommon 35 | rosidl_typesupport_interface 36 | 37 | ament_cmake_gtest 38 | ament_cmake_pytest 39 | ament_lint_auto 40 | ament_lint_common 41 | mimick_vendor 42 | performance_test_fixture 43 | 44 | rosidl_typesupport_c_packages 45 | 46 | rosidl_runtime_packages 47 | 48 | 49 | ament_cmake 50 | 51 | 52 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/include/rosidl_typesupport_c/visibility_control.h: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef ROSIDL_TYPESUPPORT_C__VISIBILITY_CONTROL_H_ 16 | #define ROSIDL_TYPESUPPORT_C__VISIBILITY_CONTROL_H_ 17 | 18 | #ifdef __cplusplus 19 | extern "C" 20 | { 21 | #endif 22 | 23 | // This logic was borrowed (then namespaced) from the examples on the gcc wiki: 24 | // https://gcc.gnu.org/wiki/Visibility 25 | 26 | #if defined _WIN32 || defined __CYGWIN__ 27 | #ifdef __GNUC__ 28 | #define ROSIDL_TYPESUPPORT_C_EXPORT __attribute__ ((dllexport)) 29 | #define ROSIDL_TYPESUPPORT_C_IMPORT __attribute__ ((dllimport)) 30 | #else 31 | #define ROSIDL_TYPESUPPORT_C_EXPORT __declspec(dllexport) 32 | #define ROSIDL_TYPESUPPORT_C_IMPORT __declspec(dllimport) 33 | #endif 34 | #ifdef ROSIDL_TYPESUPPORT_C_BUILDING_DLL 35 | #define ROSIDL_TYPESUPPORT_C_PUBLIC ROSIDL_TYPESUPPORT_C_EXPORT 36 | #else 37 | #define ROSIDL_TYPESUPPORT_C_PUBLIC ROSIDL_TYPESUPPORT_C_IMPORT 38 | #endif 39 | #define ROSIDL_TYPESUPPORT_C_LOCAL 40 | #else 41 | #define ROSIDL_TYPESUPPORT_C_EXPORT __attribute__ ((visibility("default"))) 42 | #define ROSIDL_TYPESUPPORT_C_IMPORT 43 | #if __GNUC__ >= 4 44 | #define ROSIDL_TYPESUPPORT_C_PUBLIC __attribute__ ((visibility("default"))) 45 | #define ROSIDL_TYPESUPPORT_C_LOCAL __attribute__ ((visibility("hidden"))) 46 | #else 47 | #define ROSIDL_TYPESUPPORT_C_PUBLIC 48 | #define ROSIDL_TYPESUPPORT_C_LOCAL 49 | #endif 50 | #endif 51 | 52 | #ifdef __cplusplus 53 | } 54 | #endif 55 | 56 | #endif // ROSIDL_TYPESUPPORT_C__VISIBILITY_CONTROL_H_ 57 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/test/test_type_support.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Provide a symbol so they can be checked with get_typesupport_handle_function() 16 | 17 | #include "rosidl_runtime_c/message_type_support_struct.h" 18 | #include "rosidl_runtime_c/service_type_support_struct.h" 19 | #include "rosidl_typesupport_cpp/visibility_control.h" 20 | 21 | #ifdef __cplusplus 22 | extern "C" 23 | { 24 | #endif 25 | 26 | // If ROSIDL_TYPESUPPORT_CPP_PUBLIC is used, it selects dllimport instead of dllexport, but the 27 | // function still needs to be defined separately. Windows has gotten picky with its compiler 28 | // warnings recently. 29 | #if defined _WIN32 || defined __CYGWIN__ 30 | __declspec(dllexport) const rosidl_message_type_support_t * test_message_type_support(); 31 | __declspec(dllexport) const rosidl_service_type_support_t * test_service_type_support(); 32 | #else 33 | const rosidl_message_type_support_t * test_message_type_support(); 34 | const rosidl_service_type_support_t * test_service_type_support(); 35 | #endif 36 | 37 | static const rosidl_message_type_support_t message_type_support = { 38 | nullptr, nullptr, nullptr, nullptr, nullptr, nullptr 39 | }; 40 | 41 | static const rosidl_service_type_support_t service_type_support = { 42 | nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr 43 | }; 44 | 45 | const rosidl_message_type_support_t * test_message_type_support() {return &message_type_support;} 46 | 47 | const rosidl_service_type_support_t * test_service_type_support() {return &service_type_support;} 48 | 49 | #ifdef __cplusplus 50 | } 51 | #endif 52 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/include/rosidl_typesupport_cpp/visibility_control.h: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef ROSIDL_TYPESUPPORT_CPP__VISIBILITY_CONTROL_H_ 16 | #define ROSIDL_TYPESUPPORT_CPP__VISIBILITY_CONTROL_H_ 17 | 18 | #ifdef __cplusplus 19 | extern "C" 20 | { 21 | #endif 22 | 23 | // This logic was borrowed (then namespaced) from the examples on the gcc wiki: 24 | // https://gcc.gnu.org/wiki/Visibility 25 | 26 | #if defined _WIN32 || defined __CYGWIN__ 27 | #ifdef __GNUC__ 28 | #define ROSIDL_TYPESUPPORT_CPP_EXPORT __attribute__ ((dllexport)) 29 | #define ROSIDL_TYPESUPPORT_CPP_IMPORT __attribute__ ((dllimport)) 30 | #else 31 | #define ROSIDL_TYPESUPPORT_CPP_EXPORT __declspec(dllexport) 32 | #define ROSIDL_TYPESUPPORT_CPP_IMPORT __declspec(dllimport) 33 | #endif 34 | #ifdef ROSIDL_TYPESUPPORT_CPP_BUILDING_DLL 35 | #define ROSIDL_TYPESUPPORT_CPP_PUBLIC ROSIDL_TYPESUPPORT_CPP_EXPORT 36 | #else 37 | #define ROSIDL_TYPESUPPORT_CPP_PUBLIC ROSIDL_TYPESUPPORT_CPP_IMPORT 38 | #endif 39 | #define ROSIDL_TYPESUPPORT_CPP_LOCAL 40 | #else 41 | #define ROSIDL_TYPESUPPORT_CPP_EXPORT __attribute__ ((visibility("default"))) 42 | #define ROSIDL_TYPESUPPORT_CPP_IMPORT 43 | #if __GNUC__ >= 4 44 | #define ROSIDL_TYPESUPPORT_CPP_PUBLIC __attribute__ ((visibility("default"))) 45 | #define ROSIDL_TYPESUPPORT_CPP_LOCAL __attribute__ ((visibility("hidden"))) 46 | #else 47 | #define ROSIDL_TYPESUPPORT_CPP_PUBLIC 48 | #define ROSIDL_TYPESUPPORT_CPP_LOCAL 49 | #endif 50 | #endif 51 | 52 | #ifdef __cplusplus 53 | } 54 | #endif 55 | 56 | #endif // ROSIDL_TYPESUPPORT_CPP__VISIBILITY_CONTROL_H_ 57 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | rosidl_typesupport_cpp 5 | 3.4.1 6 | Generate the type support for C++ messages. 7 | 8 | Dharini Dutia 9 | Shane Loretz 10 | 11 | Apache License 2.0 12 | 13 | Chris Lalancette 14 | Dirk Thomas 15 | 16 | ament_cmake_ros_core 17 | 18 | python3 19 | 20 | rcutils 21 | rcpputils 22 | rosidl_runtime_c 23 | rosidl_typesupport_c 24 | 25 | 26 | rosidl_typesupport_introspection_cpp 27 | 28 | ament_cmake_core 29 | rosidl_typesupport_c 30 | rosidl_runtime_c 31 | rosidl_runtime_cpp 32 | 33 | ament_index_python 34 | rosidl_cli 35 | rosidl_generator_c 36 | rosidl_generator_type_description 37 | rosidl_pycommon 38 | rosidl_typesupport_interface 39 | 40 | ament_cmake_gtest 41 | ament_cmake_pytest 42 | ament_lint_auto 43 | ament_lint_common 44 | performance_test_fixture 45 | 46 | rosidl_typesupport_cpp_packages 47 | 48 | rosidl_runtime_packages 49 | 50 | 51 | ament_cmake 52 | 53 | 54 | -------------------------------------------------------------------------------- /rosidl_typesupport_tests/CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2 | Changelog for package rosidl_typesupport_tests 3 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 4 | 5 | 3.4.1 (2025-10-20) 6 | ------------------ 7 | 8 | 3.4.0 (2025-04-25) 9 | ------------------ 10 | 11 | 3.3.3 (2025-04-18) 12 | ------------------ 13 | * Uniform cmake requirement (`#163 `_) 14 | * Contributors: mosfet80 15 | 16 | 3.3.2 (2025-02-02) 17 | ------------------ 18 | 19 | 3.3.1 (2024-06-17) 20 | ------------------ 21 | 22 | 3.3.0 (2024-04-26) 23 | ------------------ 24 | 25 | 3.2.1 (2024-03-27) 26 | ------------------ 27 | * Suppress uncrustify on long lines. (`#152 `_) 28 | * Contributors: Chris Lalancette 29 | 30 | 3.2.0 (2023-06-07) 31 | ------------------ 32 | 33 | 3.1.0 (2023-04-28) 34 | ------------------ 35 | 36 | 3.0.0 (2023-04-12) 37 | ------------------ 38 | * typesupport_tests needs to be updated to C++17 (`#137 `_) 39 | * Contributors: Lucas Wendland 40 | 41 | 2.3.1 (2023-02-24) 42 | ------------------ 43 | * Fix Typesupport Introspection tests (`#133 `_) 44 | * Contributors: Cristóbal Arroyo 45 | 46 | 2.3.0 (2023-02-13) 47 | ------------------ 48 | * Make rosidl_typesupport_tests depend on rosidl_generator_cpp. (`#132 `_) 49 | * Service introspection (`#127 `_) 50 | * Contributors: Brian, Chris Lalancette 51 | 52 | 2.2.0 (2022-09-13) 53 | ------------------ 54 | 55 | 2.1.0 (2022-05-04) 56 | ------------------ 57 | 58 | 2.0.0 (2022-03-30) 59 | ------------------ 60 | 61 | 1.5.0 (2022-03-01) 62 | ------------------ 63 | 64 | 1.4.2 (2022-01-13) 65 | ------------------ 66 | 67 | 1.4.1 (2021-08-09) 68 | ------------------ 69 | 70 | 1.4.0 (2021-07-16) 71 | ------------------ 72 | 73 | 1.3.0 (2021-06-11) 74 | ------------------ 75 | 76 | 1.2.1 (2021-04-06) 77 | ------------------ 78 | 79 | 1.2.0 (2021-03-25) 80 | ------------------ 81 | 82 | 1.1.2 (2021-03-18) 83 | ------------------ 84 | 85 | 1.1.1 (2021-01-25) 86 | ------------------ 87 | 88 | 1.1.0 (2020-12-08) 89 | ------------------ 90 | 91 | 1.0.0 (2020-05-26) 92 | ------------------ 93 | 94 | 0.9.2 (2020-05-19 18:34) 95 | ------------------------ 96 | 97 | 0.9.1 (2020-05-19 18:25) 98 | ------------------------ 99 | 100 | 0.9.0 (2020-04-24) 101 | ------------------ 102 | 103 | 0.8.0 (2019-09-26) 104 | ------------------ 105 | 106 | 0.7.1 (2019-05-08) 107 | ------------------ 108 | 109 | 0.7.0 (2019-04-14) 110 | ------------------ 111 | 112 | 0.6.2 (2019-01-11) 113 | ------------------ 114 | 115 | 0.6.1 (2018-12-07) 116 | ------------------ 117 | 118 | 0.6.0 (2018-11-16) 119 | ------------------ 120 | 121 | 0.5.0 (2018-06-24) 122 | ------------------ 123 | 124 | 0.4.0 (2017-12-08) 125 | ------------------ 126 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/rosidl_typesupport_cpp/cli.py: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Open Source Robotics Foundation, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import pathlib 16 | 17 | from ament_index_python import get_package_share_directory 18 | from ament_index_python import get_resources 19 | 20 | from rosidl_cli.command.generate.extensions import GenerateCommandExtension 21 | from rosidl_cli.command.helpers import legacy_generator_arguments_file 22 | from rosidl_cli.command.translate.api import translate 23 | 24 | from rosidl_typesupport_cpp import generate_cpp 25 | 26 | 27 | class GenerateCppTypesupport(GenerateCommandExtension): 28 | 29 | def __init__(self, name, *, typesupport_implementations=None): 30 | super().__init__(name) 31 | if typesupport_implementations is None: 32 | typesupport_implementations = list( 33 | get_resources('rosidl_typesupport_cpp')) 34 | self.__typesupport_implementations = typesupport_implementations 35 | 36 | def generate( 37 | self, 38 | package_name, 39 | interface_files, 40 | include_paths, 41 | output_path 42 | ): 43 | package_share_path = pathlib.Path( 44 | get_package_share_directory('rosidl_typesupport_cpp')) 45 | 46 | templates_path = package_share_path / 'resource' 47 | 48 | # Normalize interface definition format to .idl 49 | idl_interface_files = [] 50 | non_idl_interface_files = [] 51 | for path in interface_files: 52 | if not path.endswith('.idl'): 53 | non_idl_interface_files.append(path) 54 | else: 55 | idl_interface_files.append(path) 56 | if non_idl_interface_files: 57 | idl_interface_files.extend(translate( 58 | package_name=package_name, 59 | interface_files=non_idl_interface_files, 60 | include_paths=include_paths, 61 | output_format='idl', 62 | output_path=output_path / 'tmp', 63 | )) 64 | 65 | # Generate typesupport code 66 | with legacy_generator_arguments_file( 67 | package_name=package_name, 68 | interface_files=idl_interface_files, 69 | include_paths=include_paths, 70 | templates_path=templates_path, 71 | output_path=output_path 72 | ) as path_to_arguments_file: 73 | return generate_cpp( 74 | path_to_arguments_file, 75 | self.__typesupport_implementations 76 | ) 77 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/rosidl_typesupport_c/cli.py: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Open Source Robotics Foundation, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import pathlib 16 | 17 | from ament_index_python import get_package_share_directory 18 | from ament_index_python import get_resources 19 | 20 | from rosidl_cli.command.generate.extensions import GenerateCommandExtension 21 | from rosidl_cli.command.helpers import legacy_generator_arguments_file 22 | from rosidl_cli.command.translate.api import translate 23 | 24 | from rosidl_typesupport_c import generate_c 25 | 26 | 27 | class GenerateCTypesupport(GenerateCommandExtension): 28 | 29 | def __init__(self, name, *, typesupport_implementations=None): 30 | super().__init__(name) 31 | if typesupport_implementations is None: 32 | typesupport_implementations = list( 33 | get_resources('rosidl_typesupport_c')) 34 | self.__typesupport_implementations = typesupport_implementations 35 | 36 | def generate( 37 | self, 38 | package_name, 39 | interface_files, 40 | include_paths, 41 | output_path 42 | ): 43 | generated_files = [] 44 | 45 | package_share_path = pathlib.Path( 46 | get_package_share_directory('rosidl_typesupport_c')) 47 | 48 | templates_path = package_share_path / 'resource' 49 | 50 | # Normalize interface definition format to .idl 51 | idl_interface_files = [] 52 | non_idl_interface_files = [] 53 | for path in interface_files: 54 | if not path.endswith('.idl'): 55 | non_idl_interface_files.append(path) 56 | else: 57 | idl_interface_files.append(path) 58 | if non_idl_interface_files: 59 | idl_interface_files.extend(translate( 60 | package_name=package_name, 61 | interface_files=non_idl_interface_files, 62 | include_paths=include_paths, 63 | output_format='idl', 64 | output_path=output_path / 'tmp', 65 | )) 66 | 67 | # Generate typesupport code 68 | with legacy_generator_arguments_file( 69 | package_name=package_name, 70 | interface_files=idl_interface_files, 71 | include_paths=include_paths, 72 | templates_path=templates_path, 73 | output_path=output_path 74 | ) as path_to_arguments_file: 75 | generated_files.extend(generate_c( 76 | path_to_arguments_file, 77 | self.__typesupport_implementations 78 | )) 79 | 80 | return generated_files 81 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/cmake/get_used_typesupports.cmake: -------------------------------------------------------------------------------- 1 | # Copyright 2016-2020 Open Source Robotics Foundation, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # 16 | # Get the concrete typesupport names to be used. 17 | # 18 | # The result can be overridden by setting either a CMake or environment 19 | # variable named ``STATIC_${typesupport_type}`` (all uppercase). 20 | # The variable can contain ROS IDL typesupport names separated by the platform 21 | # specific path separator. 22 | # Including an unavailable ROS IDL typesupport results in a fatal error message. 23 | # 24 | # :param var: the output variable name for the typesupport names 25 | # :type var: list of strings 26 | # :param typesupport_type: the type of the typesupport to look for 27 | # :type typesupport_type: string 28 | # 29 | # @public 30 | # 31 | function(get_used_typesupports var typesupport_type) 32 | # all type supports available 33 | ament_index_get_resources(available_typesupports "${typesupport_type}") 34 | if(available_typesupports STREQUAL "") 35 | message(FATAL_ERROR "No '${typesupport_type}' found") 36 | endif() 37 | 38 | # use explicitly provided list if provided 39 | # option() 40 | string(TOUPPER "${typesupport_type}" typesupport_type_upper) 41 | if(NOT "$ENV{STATIC_${typesupport_type_upper}}" STREQUAL "") 42 | string(REPLACE ":" ";" STATIC_${typesupport_type_upper} "$ENV{STATIC_${typesupport_type_upper}}") 43 | endif() 44 | if(NOT "${STATIC_${typesupport_type_upper}}" STREQUAL "") 45 | # check if given ROS IDL typesupports are available 46 | foreach(typesupport ${STATIC_${typesupport_type_upper}}) 47 | if(NOT "${typesupport}" IN_LIST available_typesupports) 48 | message(FATAL_ERROR 49 | "The ROS IDL typesupport '${typesupport}' specified in " 50 | "'STATIC_${typesupport_type_upper}' is not available (" 51 | "${available_typesupports})") 52 | endif() 53 | endforeach() 54 | set(selected_typesupports ${STATIC_${typesupport_type_upper}}) 55 | message(STATUS "Filtered available ROS IDL typesupport implementations: ${selected_typesupports}") 56 | set(msg_used_typesupports "selected") 57 | else() 58 | set(selected_typesupports ${available_typesupports}) 59 | set(msg_used_typesupports "all available") 60 | endif() 61 | 62 | # if only one type support is available / selected the caller might decide to 63 | # bypass the dynamic dispatch 64 | list(LENGTH selected_typesupports count) 65 | if(count EQUAL 1) 66 | set(msg_used_typesupports "single") 67 | endif() 68 | message(STATUS "Using ${msg_used_typesupports} ${typesupport_type}: ${selected_typesupports}") 69 | set(${var} "${selected_typesupports}" PARENT_SCOPE) 70 | endfunction() 71 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/resource/idl__type_support.cpp.em: -------------------------------------------------------------------------------- 1 | // generated from rosidl_typesupport_c/resource/idl__type_support.cpp.em 2 | // with input from @(package_name):@(interface_path) 3 | // generated code does not contain a copyright notice 4 | @ 5 | @####################################################################### 6 | @# EmPy template for generating __type_support.cpp files 7 | @# 8 | @# Context: 9 | @# - package_name (string) 10 | @# - interface_path (Path relative to the directory named after the package) 11 | @# - content (IdlContent, list of elements, e.g. Messages or Services) 12 | @# - type_supports (list of strings, the names of the type support packages) 13 | @####################################################################### 14 | @{ 15 | include_directives = set() 16 | }@ 17 | @####################################################################### 18 | @# Handle message 19 | @####################################################################### 20 | @{ 21 | from rosidl_parser.definition import Message 22 | }@ 23 | @[for message in content.get_elements_of_type(Message)]@ 24 | 25 | @{ 26 | TEMPLATE( 27 | 'msg__type_support.cpp.em', 28 | package_name=package_name, interface_path=interface_path, message=message, 29 | include_directives=include_directives, type_supports=type_supports) 30 | }@ 31 | @[end for]@ 32 | @ 33 | @####################################################################### 34 | @# Handle service 35 | @####################################################################### 36 | @{ 37 | from rosidl_parser.definition import Service 38 | }@ 39 | @[for service in content.get_elements_of_type(Service)]@ 40 | 41 | @{ 42 | TEMPLATE( 43 | 'srv__type_support.cpp.em', 44 | package_name=package_name, interface_path=interface_path, service=service, 45 | include_directives=include_directives, type_supports=type_supports) 46 | }@ 47 | @[end for]@ 48 | @ 49 | @####################################################################### 50 | @# Handle action 51 | @####################################################################### 52 | @{ 53 | from rosidl_parser.definition import Action 54 | }@ 55 | @[for action in content.get_elements_of_type(Action)]@ 56 | 57 | @{ 58 | TEMPLATE( 59 | 'msg__type_support.cpp.em', 60 | package_name=package_name, interface_path=interface_path, message=action.goal, 61 | include_directives=include_directives, type_supports=type_supports) 62 | }@ 63 | 64 | @{ 65 | TEMPLATE( 66 | 'msg__type_support.cpp.em', 67 | package_name=package_name, interface_path=interface_path, message=action.result, 68 | include_directives=include_directives, type_supports=type_supports) 69 | }@ 70 | 71 | @{ 72 | TEMPLATE( 73 | 'msg__type_support.cpp.em', 74 | package_name=package_name, interface_path=interface_path, message=action.feedback, 75 | include_directives=include_directives, type_supports=type_supports) 76 | }@ 77 | 78 | @{ 79 | TEMPLATE( 80 | 'srv__type_support.cpp.em', 81 | package_name=package_name, interface_path=interface_path, service=action.send_goal_service, 82 | include_directives=include_directives, type_supports=type_supports) 83 | }@ 84 | 85 | @{ 86 | TEMPLATE( 87 | 'srv__type_support.cpp.em', 88 | package_name=package_name, interface_path=interface_path, service=action.get_result_service, 89 | include_directives=include_directives, type_supports=type_supports) 90 | }@ 91 | 92 | @{ 93 | TEMPLATE( 94 | 'msg__type_support.cpp.em', 95 | package_name=package_name, interface_path=interface_path, message=action.feedback_message, 96 | include_directives=include_directives, type_supports=type_supports) 97 | }@ 98 | 99 | @{ 100 | TEMPLATE( 101 | 'action__type_support.c.em', 102 | package_name=package_name, interface_path=interface_path, action=action, 103 | include_directives=include_directives) 104 | }@ 105 | @[end for]@ 106 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/resource/idl__type_support.cpp.em: -------------------------------------------------------------------------------- 1 | // generated from rosidl_typesupport_cpp/resource/idl__type_support.cpp.em 2 | // with input from @(package_name):@(interface_path) 3 | // generated code does not contain a copyright notice 4 | @ 5 | @####################################################################### 6 | @# EmPy template for generating __type_support.c files 7 | @# 8 | @# Context: 9 | @# - package_name (string) 10 | @# - interface_path (Path relative to the directory named after the package) 11 | @# - content (IdlContent, list of elements, e.g. Messages or Services) 12 | @# - type_supports (list of strings, the names of the type support packages) 13 | @####################################################################### 14 | @{ 15 | include_directives = set() 16 | }@ 17 | @####################################################################### 18 | @# Handle message 19 | @####################################################################### 20 | @{ 21 | from rosidl_parser.definition import Message 22 | }@ 23 | @[for message in content.get_elements_of_type(Message)]@ 24 | 25 | @{ 26 | TEMPLATE( 27 | 'msg__type_support.cpp.em', 28 | package_name=package_name, interface_path=interface_path, message=message, 29 | include_directives=include_directives, type_supports=type_supports) 30 | }@ 31 | @[end for]@ 32 | @ 33 | @####################################################################### 34 | @# Handle service 35 | @####################################################################### 36 | @{ 37 | from rosidl_parser.definition import Service 38 | }@ 39 | @[for service in content.get_elements_of_type(Service)]@ 40 | 41 | @{ 42 | TEMPLATE( 43 | 'srv__type_support.cpp.em', 44 | package_name=package_name, interface_path=interface_path, service=service, 45 | include_directives=include_directives, type_supports=type_supports) 46 | }@ 47 | @[end for]@ 48 | @ 49 | @####################################################################### 50 | @# Handle action 51 | @####################################################################### 52 | @{ 53 | from rosidl_parser.definition import Action 54 | }@ 55 | @[for action in content.get_elements_of_type(Action)]@ 56 | 57 | @{ 58 | TEMPLATE( 59 | 'msg__type_support.cpp.em', 60 | package_name=package_name, interface_path=interface_path, message=action.goal, 61 | include_directives=include_directives, type_supports=type_supports) 62 | }@ 63 | 64 | @{ 65 | TEMPLATE( 66 | 'msg__type_support.cpp.em', 67 | package_name=package_name, interface_path=interface_path, message=action.result, 68 | include_directives=include_directives, type_supports=type_supports) 69 | }@ 70 | 71 | @{ 72 | TEMPLATE( 73 | 'msg__type_support.cpp.em', 74 | package_name=package_name, interface_path=interface_path, message=action.feedback, 75 | include_directives=include_directives, type_supports=type_supports) 76 | }@ 77 | 78 | @{ 79 | TEMPLATE( 80 | 'srv__type_support.cpp.em', 81 | package_name=package_name, interface_path=interface_path, service=action.send_goal_service, 82 | include_directives=include_directives, type_supports=type_supports) 83 | }@ 84 | 85 | @{ 86 | TEMPLATE( 87 | 'srv__type_support.cpp.em', 88 | package_name=package_name, interface_path=interface_path, service=action.get_result_service, 89 | include_directives=include_directives, type_supports=type_supports) 90 | }@ 91 | 92 | @{ 93 | TEMPLATE( 94 | 'msg__type_support.cpp.em', 95 | package_name=package_name, interface_path=interface_path, message=action.feedback_message, 96 | include_directives=include_directives, type_supports=type_supports) 97 | }@ 98 | 99 | @{ 100 | TEMPLATE( 101 | 'action__type_support.cpp.em', 102 | package_name=package_name, interface_path=interface_path, action=action, 103 | include_directives=include_directives) 104 | }@ 105 | @[end for]@ 106 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/resource/action__type_support.c.em: -------------------------------------------------------------------------------- 1 | @# Included from rosidl_typesupport_c/resource/idl__type_support.c.em 2 | @{ 3 | from rosidl_generator_c import idl_structure_type_to_c_typename 4 | from rosidl_generator_type_description import GET_DESCRIPTION_FUNC 5 | from rosidl_generator_type_description import GET_HASH_FUNC 6 | from rosidl_generator_type_description import GET_SOURCES_FUNC 7 | from rosidl_parser.definition import ACTION_FEEDBACK_MESSAGE_SUFFIX 8 | from rosidl_parser.definition import ACTION_GOAL_SERVICE_SUFFIX 9 | from rosidl_parser.definition import ACTION_RESULT_SERVICE_SUFFIX 10 | from rosidl_pycommon import convert_camel_case_to_lower_case_underscore 11 | 12 | include_parts = [package_name] + list(interface_path.parents[0].parts) + \ 13 | [convert_camel_case_to_lower_case_underscore(interface_path.stem)] 14 | include_base = '/'.join(include_parts) 15 | include_parts_detail = [package_name] + list(interface_path.parents[0].parts) + [ 16 | 'detail', convert_camel_case_to_lower_case_underscore(interface_path.stem)] 17 | include_base_detail = '/'.join(include_parts_detail) 18 | 19 | header_files = ( 20 | 'action_msgs/msg/goal_status_array.h', 21 | 'action_msgs/srv/cancel_goal.h', 22 | include_base + '.h', 23 | include_base_detail + '__type_support.h', 24 | ) 25 | }@ 26 | @[for header_file in header_files]@ 27 | @[ if header_file in include_directives]@ 28 | // already included above 29 | // @ 30 | @[ else]@ 31 | @{include_directives.add(header_file)}@ 32 | @[ end if]@ 33 | #include "@(header_file)" 34 | @[end for]@ 35 | 36 | static rosidl_action_type_support_t _@('__'.join([package_name] + list(interface_path.parents[0].parts)))__@(interface_path.stem)__typesupport_c = { 37 | NULL, NULL, NULL, NULL, NULL, 38 | &@(idl_structure_type_to_c_typename(action.namespaced_type))__@(GET_HASH_FUNC), 39 | &@(idl_structure_type_to_c_typename(action.namespaced_type))__@(GET_DESCRIPTION_FUNC), 40 | &@(idl_structure_type_to_c_typename(action.namespaced_type))__@(GET_SOURCES_FUNC), 41 | }; 42 | 43 | #ifdef __cplusplus 44 | extern "C" 45 | { 46 | #endif 47 | 48 | const rosidl_action_type_support_t * 49 | ROSIDL_TYPESUPPORT_INTERFACE__ACTION_SYMBOL_NAME( 50 | rosidl_typesupport_c, @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(interface_path.stem))() 51 | { 52 | // Thread-safe by always writing the same values to the static struct 53 | _@('__'.join([package_name] + list(interface_path.parents[0].parts)))__@(interface_path.stem)__typesupport_c.goal_service_type_support = 54 | ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME( 55 | rosidl_typesupport_c, @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(interface_path.stem)@(ACTION_GOAL_SERVICE_SUFFIX))(); 56 | _@('__'.join([package_name] + list(interface_path.parents[0].parts)))__@(interface_path.stem)__typesupport_c.result_service_type_support = 57 | ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME( 58 | rosidl_typesupport_c, @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(interface_path.stem)@(ACTION_RESULT_SERVICE_SUFFIX))(); 59 | _@('__'.join([package_name] + list(interface_path.parents[0].parts)))__@(interface_path.stem)__typesupport_c.cancel_service_type_support = 60 | ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME( 61 | rosidl_typesupport_c, action_msgs, srv, CancelGoal)(); 62 | _@('__'.join([package_name] + list(interface_path.parents[0].parts)))__@(interface_path.stem)__typesupport_c.feedback_message_type_support = 63 | ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME( 64 | rosidl_typesupport_c, @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(interface_path.stem)@(ACTION_FEEDBACK_MESSAGE_SUFFIX))(); 65 | _@('__'.join([package_name] + list(interface_path.parents[0].parts)))__@(interface_path.stem)__typesupport_c.status_message_type_support = 66 | ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME( 67 | rosidl_typesupport_c, action_msgs, msg, GoalStatusArray)(); 68 | 69 | return &_@('__'.join([package_name] + list(interface_path.parents[0].parts)))__@(interface_path.stem)__typesupport_c; 70 | } 71 | 72 | #ifdef __cplusplus 73 | } 74 | #endif 75 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/resource/action__type_support.cpp.em: -------------------------------------------------------------------------------- 1 | @# Included from rosidl_typesupport_cpp/resource/idl__type_support.cpp.em 2 | @{ 3 | from rosidl_generator_c import idl_structure_type_to_c_typename 4 | from rosidl_generator_type_description import GET_DESCRIPTION_FUNC 5 | from rosidl_generator_type_description import GET_HASH_FUNC 6 | from rosidl_generator_type_description import GET_SOURCES_FUNC 7 | from rosidl_pycommon import convert_camel_case_to_lower_case_underscore 8 | include_parts = [package_name] + list(interface_path.parents[0].parts) + [ 9 | 'detail', convert_camel_case_to_lower_case_underscore(interface_path.stem)] 10 | include_base = '/'.join(include_parts) 11 | 12 | header_files = ( 13 | 'action_msgs/msg/goal_status_array.hpp', 14 | 'action_msgs/srv/cancel_goal.hpp', 15 | include_base + '__struct.hpp', 16 | 'rosidl_typesupport_cpp/visibility_control.h', 17 | 'rosidl_runtime_c/action_type_support_struct.h', 18 | 'rosidl_typesupport_cpp/action_type_support.hpp', 19 | 'rosidl_typesupport_cpp/message_type_support.hpp', 20 | 'rosidl_typesupport_cpp/service_type_support.hpp', 21 | ) 22 | }@ 23 | @[for header_file in header_files]@ 24 | @[ if header_file in include_directives]@ 25 | // already included above 26 | // @ 27 | @[ else]@ 28 | @{include_directives.add(header_file)}@ 29 | @[ end if]@ 30 | #include "@(header_file)" 31 | @[end for]@ 32 | @ 33 | @[ for ns in action.namespaced_type.namespaces]@ 34 | 35 | namespace @(ns) 36 | { 37 | @[ end for]@ 38 | 39 | namespace rosidl_typesupport_cpp 40 | { 41 | 42 | static rosidl_action_type_support_t @(interface_path.stem)_action_type_support_handle = { 43 | NULL, NULL, NULL, NULL, NULL, 44 | &@(idl_structure_type_to_c_typename(action.namespaced_type))__@(GET_HASH_FUNC), 45 | &@(idl_structure_type_to_c_typename(action.namespaced_type))__@(GET_DESCRIPTION_FUNC), 46 | &@(idl_structure_type_to_c_typename(action.namespaced_type))__@(GET_SOURCES_FUNC), 47 | }; 48 | 49 | } // namespace rosidl_typesupport_cpp 50 | @[ for ns in reversed(action.namespaced_type.namespaces)]@ 51 | 52 | } // namespace @(ns) 53 | @[ end for]@ 54 | 55 | namespace rosidl_typesupport_cpp 56 | { 57 | 58 | template<> 59 | ROSIDL_TYPESUPPORT_CPP_PUBLIC 60 | const rosidl_action_type_support_t * 61 | get_action_type_support_handle<@('::'.join([package_name] + list(interface_path.parents[0].parts)))::@(interface_path.stem)>() 62 | { 63 | using ::@('::'.join([package_name] + list(interface_path.parents[0].parts)))::rosidl_typesupport_cpp::@(interface_path.stem)_action_type_support_handle; 64 | // Thread-safe by always writing the same values to the static struct 65 | @(interface_path.stem)_action_type_support_handle.goal_service_type_support = get_service_type_support_handle<::@('::'.join([package_name] + list(interface_path.parents[0].parts)))::@(interface_path.stem)::Impl::SendGoalService>(); 66 | @(interface_path.stem)_action_type_support_handle.result_service_type_support = get_service_type_support_handle<::@('::'.join([package_name] + list(interface_path.parents[0].parts)))::@(interface_path.stem)::Impl::GetResultService>(); 67 | @(interface_path.stem)_action_type_support_handle.cancel_service_type_support = get_service_type_support_handle<::@('::'.join([package_name] + list(interface_path.parents[0].parts)))::@(interface_path.stem)::Impl::CancelGoalService>(); 68 | @(interface_path.stem)_action_type_support_handle.feedback_message_type_support = get_message_type_support_handle<::@('::'.join([package_name] + list(interface_path.parents[0].parts)))::@(interface_path.stem)::Impl::FeedbackMessage>(); 69 | @(interface_path.stem)_action_type_support_handle.status_message_type_support = get_message_type_support_handle<::@('::'.join([package_name] + list(interface_path.parents[0].parts)))::@(interface_path.stem)::Impl::GoalStatusMessage>(); 70 | return &@(interface_path.stem)_action_type_support_handle; 71 | } 72 | 73 | } // namespace rosidl_typesupport_cpp 74 | 75 | #ifdef __cplusplus 76 | extern "C" 77 | { 78 | #endif 79 | 80 | ROSIDL_TYPESUPPORT_CPP_PUBLIC 81 | const rosidl_action_type_support_t * 82 | ROSIDL_TYPESUPPORT_INTERFACE__ACTION_SYMBOL_NAME(rosidl_typesupport_cpp, @(', '.join([package_name] + list(interface_path.parents[0].parts) + [interface_path.stem])))() { 83 | return ::rosidl_typesupport_cpp::get_action_type_support_handle<@('::'.join([package_name] + list(interface_path.parents[0].parts) + [interface_path.stem]))>(); 84 | } 85 | 86 | #ifdef __cplusplus 87 | } 88 | #endif 89 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/src/type_support_dispatch.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef TYPE_SUPPORT_DISPATCH_HPP_ 16 | #define TYPE_SUPPORT_DISPATCH_HPP_ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "rcpputils/shared_library.hpp" 26 | #include "rcutils/error_handling.h" 27 | #include "rcutils/snprintf.h" 28 | #include "rosidl_typesupport_c/type_support_map.h" 29 | 30 | namespace rosidl_typesupport_cpp 31 | { 32 | 33 | extern const char * typesupport_identifier; 34 | 35 | template 36 | const TypeSupport * 37 | get_typesupport_handle_function( 38 | const TypeSupport * handle, const char * identifier) noexcept 39 | { 40 | if (strcmp(handle->typesupport_identifier, identifier) == 0) { 41 | return handle; 42 | } 43 | 44 | if (strcmp( 45 | handle->typesupport_identifier, 46 | rosidl_typesupport_cpp::typesupport_identifier) == 0) 47 | { 48 | const type_support_map_t * map = \ 49 | static_cast(handle->data); 50 | for (size_t i = 0; i < map->size; ++i) { 51 | if (strcmp(map->typesupport_identifier[i], identifier) != 0) { 52 | continue; 53 | } 54 | rcpputils::SharedLibrary * lib = nullptr; 55 | 56 | if (!map->data[i]) { 57 | char library_basename[1024]; 58 | int ret = rcutils_snprintf( 59 | library_basename, 1023, "%s__%s", 60 | map->package_name, identifier); 61 | if (ret < 0) { 62 | RCUTILS_SET_ERROR_MSG("Failed to format library name"); 63 | return nullptr; 64 | } 65 | 66 | std::string library_name; 67 | try { 68 | library_name = rcpputils::get_platform_library_name(library_basename); 69 | } catch (const std::runtime_error & e) { 70 | RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( 71 | "Failed to compute library name for '%s' due to %s", 72 | library_basename, e.what()); 73 | return nullptr; 74 | } 75 | 76 | try { 77 | lib = new rcpputils::SharedLibrary(library_name); 78 | } catch (const std::runtime_error & e) { 79 | RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( 80 | "Could not load library %s: %s", library_name.c_str(), e.what()); 81 | return nullptr; 82 | } catch (const std::bad_alloc & e) { 83 | RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( 84 | "Could not load library %s: %s", library_name.c_str(), e.what()); 85 | return nullptr; 86 | } 87 | map->data[i] = lib; 88 | } 89 | auto clib = static_cast(map->data[i]); 90 | lib = const_cast(clib); 91 | 92 | void * sym = nullptr; 93 | 94 | try { 95 | if (!lib->has_symbol(map->symbol_name[i])) { 96 | RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( 97 | "Failed to find symbol '%s' in library", map->symbol_name[i]); 98 | return nullptr; 99 | } 100 | sym = lib->get_symbol(map->symbol_name[i]); 101 | } catch (const std::exception & e) { 102 | RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( 103 | "Failed to get symbol '%s' in library: %s", 104 | map->symbol_name[i], e.what()); 105 | return nullptr; 106 | } 107 | 108 | typedef const TypeSupport * (* funcSignature)(void); 109 | funcSignature func = reinterpret_cast(sym); 110 | const TypeSupport * ts = func(); 111 | return ts; 112 | } 113 | } 114 | RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( 115 | "Handle's typesupport identifier (%s) is not supported by this library", 116 | handle->typesupport_identifier); 117 | return nullptr; 118 | } 119 | 120 | } // namespace rosidl_typesupport_cpp 121 | 122 | #endif // TYPE_SUPPORT_DISPATCH_HPP_ 123 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/src/type_support_dispatch.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef TYPE_SUPPORT_DISPATCH_HPP_ 16 | #define TYPE_SUPPORT_DISPATCH_HPP_ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include "rcpputils/shared_library.hpp" 27 | #include "rcutils/error_handling.h" 28 | #include "rcutils/snprintf.h" 29 | #include "rosidl_typesupport_c/identifier.h" 30 | #include "rosidl_typesupport_c/type_support_map.h" 31 | 32 | namespace rosidl_typesupport_c 33 | { 34 | 35 | extern const char * typesupport_identifier; 36 | 37 | template 38 | const TypeSupport * 39 | get_typesupport_handle_function( 40 | const TypeSupport * handle, const char * identifier) 41 | { 42 | if (strcmp(handle->typesupport_identifier, identifier) == 0) { 43 | return handle; 44 | } 45 | 46 | if (strcmp( 47 | handle->typesupport_identifier, 48 | rosidl_typesupport_c__typesupport_identifier) == 0) 49 | { 50 | const type_support_map_t * map = \ 51 | static_cast(handle->data); 52 | for (size_t i = 0; i < map->size; ++i) { 53 | if (strcmp(map->typesupport_identifier[i], identifier) != 0) { 54 | continue; 55 | } 56 | rcpputils::SharedLibrary * lib = nullptr; 57 | 58 | if (!map->data[i]) { 59 | char library_basename[1024]; 60 | int ret = rcutils_snprintf( 61 | library_basename, 1023, "%s__%s", 62 | map->package_name, identifier); 63 | if (ret < 0) { 64 | RCUTILS_SET_ERROR_MSG("Failed to format library name"); 65 | return nullptr; 66 | } 67 | 68 | std::string library_name; 69 | try { 70 | library_name = rcpputils::get_platform_library_name(library_basename); 71 | } catch (const std::exception & e) { 72 | RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( 73 | "Failed to compute library name for '%s' due to %s", 74 | library_basename, e.what()); 75 | return nullptr; 76 | } 77 | 78 | try { 79 | lib = new rcpputils::SharedLibrary(library_name); 80 | } catch (const std::runtime_error & e) { 81 | RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( 82 | "Could not load library %s: %s", library_name.c_str(), e.what()); 83 | return nullptr; 84 | } catch (const std::bad_alloc & e) { 85 | RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( 86 | "Could not load library %s: %s", library_name.c_str(), e.what()); 87 | return nullptr; 88 | } 89 | map->data[i] = lib; 90 | } 91 | auto clib = static_cast(map->data[i]); 92 | lib = const_cast(clib); 93 | 94 | void * sym = nullptr; 95 | 96 | try { 97 | if (!lib->has_symbol(map->symbol_name[i])) { 98 | RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( 99 | "Failed to find symbol '%s' in library", map->symbol_name[i]); 100 | return nullptr; 101 | } 102 | sym = lib->get_symbol(map->symbol_name[i]); 103 | } catch (const std::exception & e) { 104 | RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( 105 | "Failed to get symbol '%s' in library: %s", 106 | map->symbol_name[i], e.what()); 107 | return nullptr; 108 | } 109 | 110 | typedef const TypeSupport * (* funcSignature)(void); 111 | funcSignature func = reinterpret_cast(sym); 112 | const TypeSupport * ts = func(); 113 | return ts; 114 | } 115 | } 116 | RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING( 117 | "Handle's typesupport identifier (%s) is not supported by this library", 118 | handle->typesupport_identifier); 119 | return nullptr; 120 | } 121 | 122 | } // namespace rosidl_typesupport_c 123 | 124 | #endif // TYPE_SUPPORT_DISPATCH_HPP_ 125 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/test/benchmark/benchmark_type_support_dispatch.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "rcpputils/shared_library.hpp" 16 | #include "rcutils/macros.h" 17 | #include "rosidl_typesupport_c/identifier.h" 18 | #include "rosidl_typesupport_c/message_type_support_dispatch.h" 19 | #include "rosidl_typesupport_c/service_type_support_dispatch.h" 20 | #include "rosidl_typesupport_c/type_support_map.h" 21 | 22 | #include "performance_test_fixture/performance_test_fixture.hpp" 23 | 24 | using performance_test_fixture::PerformanceTest; 25 | 26 | constexpr size_t map_size = 4u; 27 | constexpr const char package_name[] = "rosidl_typesupport_c"; 28 | constexpr const char * identifiers[map_size] = { 29 | "test_type_support1", "test_type_support2", "test_type_support3", "test_type_support4" 30 | }; 31 | 32 | constexpr const char * symbols[map_size] = { 33 | "test_message_type_support", 34 | "test_message_type_support2", 35 | "test_message_type_support3", 36 | "test_message_type_support4" 37 | }; 38 | 39 | rosidl_message_type_support_t get_rosidl_message_type_support(const char * identifier) 40 | { 41 | return {identifier, nullptr, nullptr, nullptr, nullptr, nullptr}; 42 | } 43 | 44 | rosidl_service_type_support_t get_rosidl_service_type_support(const char * identifier) 45 | { 46 | return { 47 | identifier, 48 | nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr 49 | }; 50 | } 51 | 52 | type_support_map_t get_typesupport_map(void ** library_array) 53 | { 54 | return type_support_map_t{ 55 | map_size, 56 | package_name, 57 | identifiers, 58 | symbols, 59 | library_array, 60 | }; 61 | } 62 | 63 | BENCHMARK_F(PerformanceTest, message_typesupport_handle_function)(benchmark::State & st) 64 | { 65 | rosidl_message_type_support_t type_support_c_identifier = 66 | get_rosidl_message_type_support(rosidl_typesupport_c__typesupport_identifier); 67 | rcpputils::SharedLibrary * library_array[map_size] = {nullptr, nullptr, nullptr}; 68 | type_support_map_t support_map = get_typesupport_map(reinterpret_cast(&library_array)); 69 | type_support_c_identifier.data = &support_map; 70 | 71 | reset_heap_counters(); 72 | 73 | for (auto _ : st) { 74 | RCUTILS_UNUSED(_); 75 | // Successfully load library and find symbols 76 | auto * result = rosidl_typesupport_c__get_message_typesupport_handle_function( 77 | &type_support_c_identifier, 78 | "test_type_support1"); 79 | if (nullptr == result) { 80 | st.SkipWithError("rosidl_typesupport_c__get_message_typesupport_handle_function failed"); 81 | } 82 | // Unload for the next iteration 83 | for (size_t i = 0; i < map_size; i++) { 84 | if (library_array[i] != nullptr) { 85 | delete library_array[i]; 86 | library_array[i] = nullptr; 87 | } 88 | } 89 | } 90 | } 91 | 92 | BENCHMARK_F(PerformanceTest, service_typesupport_handle_function)(benchmark::State & st) 93 | { 94 | rosidl_service_type_support_t type_support_c_identifier = 95 | get_rosidl_service_type_support(rosidl_typesupport_c__typesupport_identifier); 96 | rcpputils::SharedLibrary * library_array[map_size] = {nullptr, nullptr, nullptr}; 97 | type_support_map_t support_map = get_typesupport_map(reinterpret_cast(&library_array)); 98 | type_support_c_identifier.data = &support_map; 99 | 100 | reset_heap_counters(); 101 | 102 | for (auto _ : st) { 103 | RCUTILS_UNUSED(_); 104 | // Successfully load library and find symbols 105 | auto * result = rosidl_typesupport_c__get_service_typesupport_handle_function( 106 | &type_support_c_identifier, 107 | "test_type_support1"); 108 | if (nullptr == result) { 109 | st.SkipWithError("rosidl_typesupport_c__get_service_typesupport_handle_function failed"); 110 | } 111 | // Unload for the next iteration 112 | for (size_t i = 0; i < map_size; i++) { 113 | if (library_array[i] != nullptr) { 114 | delete library_array[i]; 115 | library_array[i] = nullptr; 116 | } 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/test/benchmark/benchmark_type_support_dispatch.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "rcpputils/shared_library.hpp" 16 | #include "rcutils/macros.h" 17 | #include "rosidl_typesupport_cpp/identifier.hpp" 18 | #include "rosidl_typesupport_cpp/message_type_support_dispatch.hpp" 19 | #include "rosidl_typesupport_cpp/service_type_support_dispatch.hpp" 20 | #include "rosidl_typesupport_c/type_support_map.h" 21 | 22 | #include "performance_test_fixture/performance_test_fixture.hpp" 23 | 24 | using performance_test_fixture::PerformanceTest; 25 | 26 | constexpr size_t map_size = 4u; 27 | constexpr const char package_name[] = "rosidl_typesupport_cpp"; 28 | constexpr const char * identifiers[map_size] = { 29 | "test_type_support1", "test_type_support2", "test_type_support3", "test_type_support4" 30 | }; 31 | 32 | constexpr const char * symbols[map_size] = { 33 | "test_message_type_support", 34 | "test_message_type_support2", 35 | "test_message_type_support3", 36 | "test_message_type_support4" 37 | }; 38 | 39 | rosidl_message_type_support_t get_rosidl_message_type_support(const char * identifier) 40 | { 41 | return {identifier, nullptr, nullptr, nullptr, nullptr, nullptr}; 42 | } 43 | 44 | rosidl_service_type_support_t get_rosidl_service_type_support(const char * identifier) 45 | { 46 | return { 47 | identifier, 48 | nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr 49 | }; 50 | } 51 | 52 | type_support_map_t get_typesupport_map(void ** library_array) 53 | { 54 | return type_support_map_t{ 55 | map_size, 56 | package_name, 57 | identifiers, 58 | symbols, 59 | library_array, 60 | }; 61 | } 62 | 63 | BENCHMARK_F(PerformanceTest, message_typesupport_handle_function)(benchmark::State & st) 64 | { 65 | rosidl_message_type_support_t type_support_cpp_identifier = 66 | get_rosidl_message_type_support(rosidl_typesupport_cpp::typesupport_identifier); 67 | rcpputils::SharedLibrary * library_array[map_size] = {nullptr, nullptr, nullptr}; 68 | type_support_map_t support_map = get_typesupport_map(reinterpret_cast(&library_array)); 69 | type_support_cpp_identifier.data = &support_map; 70 | 71 | reset_heap_counters(); 72 | 73 | for (auto _ : st) { 74 | RCUTILS_UNUSED(_); 75 | // Successfully load library and find symbols 76 | auto * result = rosidl_typesupport_cpp::get_message_typesupport_handle_function( 77 | &type_support_cpp_identifier, 78 | "test_type_support1"); 79 | if (nullptr == result) { 80 | st.SkipWithError("rosidl_typesupport_cpp::get_message_typesupport_handle_function failed"); 81 | } 82 | // Unload for the next iteration 83 | for (size_t i = 0; i < map_size; i++) { 84 | if (library_array[i] != nullptr) { 85 | delete library_array[i]; 86 | library_array[i] = nullptr; 87 | } 88 | } 89 | } 90 | } 91 | 92 | BENCHMARK_F(PerformanceTest, service_typesupport_handle_function)(benchmark::State & st) 93 | { 94 | rosidl_service_type_support_t type_support_cpp_identifier = 95 | get_rosidl_service_type_support(rosidl_typesupport_cpp::typesupport_identifier); 96 | rcpputils::SharedLibrary * library_array[map_size] = {nullptr, nullptr, nullptr}; 97 | type_support_map_t support_map = get_typesupport_map(reinterpret_cast(&library_array)); 98 | type_support_cpp_identifier.data = &support_map; 99 | 100 | reset_heap_counters(); 101 | 102 | for (auto _ : st) { 103 | RCUTILS_UNUSED(_); 104 | // Successfully load library and find symbols 105 | auto * result = rosidl_typesupport_cpp::get_service_typesupport_handle_function( 106 | &type_support_cpp_identifier, 107 | "test_type_support1"); 108 | if (nullptr == result) { 109 | st.SkipWithError("rosidl_typesupport_cpp::get_service_typesupport_handle_function failed"); 110 | } 111 | // Unload for the next iteration 112 | for (size_t i = 0; i < map_size; i++) { 113 | if (library_array[i] != nullptr) { 114 | delete library_array[i]; 115 | library_array[i] = nullptr; 116 | } 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.20) 2 | 3 | project(rosidl_typesupport_cpp) 4 | 5 | # Default to C++17 6 | if(NOT CMAKE_CXX_STANDARD) 7 | set(CMAKE_CXX_STANDARD 17) 8 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 9 | endif() 10 | 11 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 12 | add_compile_options(-Wall -Wextra -Wpedantic) 13 | endif() 14 | 15 | find_package(ament_cmake_ros_core REQUIRED) 16 | find_package(rcutils REQUIRED) 17 | find_package(rcpputils REQUIRED) 18 | find_package(rosidl_runtime_c REQUIRED) 19 | find_package(rosidl_typesupport_c REQUIRED) 20 | 21 | ament_export_dependencies(rcutils) 22 | ament_export_dependencies(rcpputils) 23 | ament_export_dependencies(rosidl_runtime_c) 24 | ament_export_dependencies(rosidl_typesupport_c) 25 | 26 | ament_python_install_package(${PROJECT_NAME}) 27 | 28 | add_library(${PROJECT_NAME} 29 | src/identifier.cpp 30 | src/message_type_support_dispatch.cpp 31 | src/service_type_support_dispatch.cpp) 32 | if(WIN32) 33 | target_compile_definitions(${PROJECT_NAME} 34 | PRIVATE "ROSIDL_TYPESUPPORT_CPP_BUILDING_DLL") 35 | endif() 36 | target_include_directories(${PROJECT_NAME} PUBLIC 37 | "$" 38 | "$") 39 | 40 | target_link_libraries(${PROJECT_NAME} PUBLIC 41 | rosidl_runtime_c::rosidl_runtime_c 42 | rosidl_typesupport_c::rosidl_typesupport_c) 43 | target_link_libraries(${PROJECT_NAME} PRIVATE 44 | rcpputils::rcpputils 45 | rcutils::rcutils) 46 | 47 | # Export old-style CMake variables 48 | ament_export_include_directories("include/${PROJECT_NAME}") 49 | ament_export_libraries(${PROJECT_NAME}) 50 | 51 | # Export modern CMake targets 52 | ament_export_targets(${PROJECT_NAME}) 53 | 54 | ament_index_register_resource("rosidl_runtime_packages") 55 | 56 | if(BUILD_TESTING) 57 | find_package(ament_lint_auto REQUIRED) 58 | ament_lint_auto_find_test_dependencies() 59 | 60 | find_package(performance_test_fixture REQUIRED) 61 | # Give cppcheck hints about macro definitions coming from outside this package 62 | get_target_property(ament_cmake_cppcheck_ADDITIONAL_INCLUDE_DIRS 63 | performance_test_fixture::performance_test_fixture INTERFACE_INCLUDE_DIRECTORIES) 64 | 65 | set(TEST_LIB_DIR "${CMAKE_CURRENT_BINARY_DIR}/test_libs") 66 | 67 | add_library(rosidl_typesupport_cpp__test_type_support1 68 | test/test_type_support.cpp) 69 | target_link_libraries(rosidl_typesupport_cpp__test_type_support1 ${PROJECT_NAME}) 70 | add_custom_command(TARGET rosidl_typesupport_cpp__test_type_support1 POST_BUILD 71 | COMMAND ${CMAKE_COMMAND} -E copy 72 | $ 73 | ${TEST_LIB_DIR}) 74 | 75 | # This same library is added a second type with a new name for additional tests 76 | add_library(rosidl_typesupport_cpp__test_type_support2 77 | test/test_type_support.cpp) 78 | target_link_libraries(rosidl_typesupport_cpp__test_type_support2 ${PROJECT_NAME}) 79 | add_custom_command(TARGET rosidl_typesupport_cpp__test_type_support2 POST_BUILD 80 | COMMAND ${CMAKE_COMMAND} -E copy 81 | $ 82 | ${TEST_LIB_DIR}) 83 | 84 | find_package(ament_cmake_gtest REQUIRED) 85 | 86 | ament_add_gtest(test_message_type_support test/test_message_type_support_dispatch.cpp 87 | APPEND_ENV 88 | "DYLD_LIBRARY_PATH=${TEST_LIB_DIR}" 89 | "LD_LIBRARY_PATH=${TEST_LIB_DIR}" 90 | "PATH=${TEST_LIB_DIR}") 91 | if(TARGET test_message_type_support) 92 | target_link_libraries(test_message_type_support 93 | ${PROJECT_NAME} 94 | rcutils::rcutils 95 | rcpputils::rcpputils 96 | ) 97 | target_compile_definitions(test_message_type_support PUBLIC RCUTILS_ENABLE_FAULT_INJECTION) 98 | endif() 99 | 100 | ament_add_gtest(test_service_type_support test/test_service_type_support_dispatch.cpp 101 | APPEND_ENV 102 | "DYLD_LIBRARY_PATH=${TEST_LIB_DIR}" 103 | "LD_LIBRARY_PATH=${TEST_LIB_DIR}" 104 | "PATH=${TEST_LIB_DIR}") 105 | if(TARGET test_service_type_support) 106 | target_link_libraries(test_service_type_support 107 | ${PROJECT_NAME} 108 | rcutils::rcutils 109 | rcpputils::rcpputils 110 | ) 111 | target_compile_definitions(test_service_type_support PUBLIC RCUTILS_ENABLE_FAULT_INJECTION) 112 | endif() 113 | 114 | # Test type_support_dispatch throws runtime error when trying to load this "library" 115 | file(GENERATE 116 | OUTPUT 117 | "${TEST_LIB_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}rosidl_typesupport_cpp__test_type_support3${CMAKE_SHARED_LIBRARY_SUFFIX}" 118 | CONTENT "I'm not a shared library, why would you treat me like one?") 119 | 120 | add_performance_test(benchmark_type_support_dispatch test/benchmark/benchmark_type_support_dispatch.cpp 121 | APPEND_ENV 122 | "DYLD_LIBRARY_PATH=${TEST_LIB_DIR}" 123 | "LD_LIBRARY_PATH=${TEST_LIB_DIR}" 124 | "PATH=${TEST_LIB_DIR}") 125 | if(TARGET benchmark_type_support_dispatch) 126 | target_link_libraries(benchmark_type_support_dispatch 127 | ${PROJECT_NAME} 128 | rcpputils::rcpputils) 129 | endif() 130 | 131 | find_package(ament_cmake_pytest REQUIRED) 132 | ament_add_pytest_test(test_cli_extension test/test_cli_extension.py) 133 | endif() 134 | 135 | if(BUILD_SHARED_LIBS) 136 | set(${PROJECT_NAME}_LIBRARY_TYPE "SHARED") 137 | else() 138 | set(${PROJECT_NAME}_LIBRARY_TYPE "STATIC") 139 | endif() 140 | 141 | ament_package( 142 | CONFIG_EXTRAS "rosidl_typesupport_cpp-extras.cmake.in" 143 | ) 144 | 145 | install( 146 | PROGRAMS bin/rosidl_typesupport_cpp 147 | DESTINATION lib/rosidl_typesupport_cpp 148 | ) 149 | install( 150 | DIRECTORY cmake resource 151 | DESTINATION share/${PROJECT_NAME} 152 | ) 153 | install( 154 | DIRECTORY include/ 155 | DESTINATION include/${PROJECT_NAME} 156 | ) 157 | install( 158 | TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME} 159 | ARCHIVE DESTINATION lib 160 | LIBRARY DESTINATION lib 161 | RUNTIME DESTINATION bin 162 | ) 163 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.20) 2 | 3 | project(rosidl_typesupport_c) 4 | 5 | # Default to C11 6 | if(NOT CMAKE_C_STANDARD) 7 | set(CMAKE_C_STANDARD 11) 8 | endif() 9 | 10 | # Default to C++17 11 | if(NOT CMAKE_CXX_STANDARD) 12 | set(CMAKE_CXX_STANDARD 17) 13 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 14 | endif() 15 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 16 | add_compile_options(-Wall -Wextra -Wpedantic) 17 | endif() 18 | 19 | find_package(ament_cmake_ros_core REQUIRED) 20 | find_package(rcpputils REQUIRED) 21 | find_package(rcutils REQUIRED) 22 | find_package(rosidl_runtime_c REQUIRED) 23 | 24 | ament_export_dependencies(rcutils) 25 | ament_export_dependencies(rcpputils) 26 | ament_export_dependencies(rosidl_runtime_c) 27 | ament_export_dependencies(rosidl_typesupport_interface) 28 | 29 | ament_python_install_package(${PROJECT_NAME}) 30 | 31 | add_library(${PROJECT_NAME} 32 | src/identifier.c 33 | src/message_type_support_dispatch.cpp 34 | src/service_type_support_dispatch.cpp) 35 | if(WIN32) 36 | target_compile_definitions(${PROJECT_NAME} 37 | PRIVATE "ROSIDL_TYPESUPPORT_C_BUILDING_DLL") 38 | endif() 39 | target_include_directories(${PROJECT_NAME} PUBLIC 40 | "$" 41 | "$") 42 | 43 | target_link_libraries(${PROJECT_NAME} PUBLIC 44 | rosidl_runtime_c::rosidl_runtime_c) 45 | target_link_libraries(${PROJECT_NAME} PRIVATE 46 | rcpputils::rcpputils 47 | rcutils::rcutils) 48 | 49 | # Export old-style CMake variables 50 | ament_export_include_directories("include/${PROJECT_NAME}") 51 | ament_export_libraries(${PROJECT_NAME}) 52 | 53 | # Export modern CMake targets 54 | ament_export_targets(${PROJECT_NAME}) 55 | 56 | ament_index_register_resource("rosidl_runtime_packages") 57 | 58 | if(BUILD_TESTING) 59 | find_package(ament_lint_auto REQUIRED) 60 | ament_lint_auto_find_test_dependencies() 61 | 62 | find_package(performance_test_fixture REQUIRED) 63 | # Give cppcheck hints about macro definitions coming from outside this package 64 | get_target_property(ament_cmake_cppcheck_ADDITIONAL_INCLUDE_DIRS 65 | performance_test_fixture::performance_test_fixture INTERFACE_INCLUDE_DIRECTORIES) 66 | 67 | set(TEST_LIB_DIR "${CMAKE_CURRENT_BINARY_DIR}/test_libs") 68 | 69 | add_library(rosidl_typesupport_c__test_type_support1 70 | test/test_type_support.c) 71 | target_link_libraries(rosidl_typesupport_c__test_type_support1 ${PROJECT_NAME}) 72 | add_custom_command(TARGET rosidl_typesupport_c__test_type_support1 POST_BUILD 73 | COMMAND ${CMAKE_COMMAND} -E copy 74 | $ 75 | ${TEST_LIB_DIR}) 76 | 77 | # This same library is added a second type with a new name for additional tests 78 | add_library(rosidl_typesupport_c__test_type_support2 79 | test/test_type_support.c) 80 | target_link_libraries(rosidl_typesupport_c__test_type_support2 ${PROJECT_NAME}) 81 | add_custom_command(TARGET rosidl_typesupport_c__test_type_support2 POST_BUILD 82 | COMMAND ${CMAKE_COMMAND} -E copy 83 | $ 84 | ${TEST_LIB_DIR}) 85 | 86 | find_package(ament_cmake_gtest REQUIRED) 87 | 88 | ament_add_gtest(test_message_type_support test/test_message_type_support_dispatch.cpp 89 | APPEND_ENV 90 | "DYLD_LIBRARY_PATH=${TEST_LIB_DIR}" 91 | "LD_LIBRARY_PATH=${TEST_LIB_DIR}" 92 | "PATH=${TEST_LIB_DIR}") 93 | ament_add_test_label(test_message_type_support mimick) 94 | if(TARGET test_message_type_support) 95 | target_link_libraries(test_message_type_support 96 | ${PROJECT_NAME} 97 | mimick 98 | rcpputils::rcpputils 99 | ) 100 | target_compile_definitions(test_message_type_support PUBLIC RCUTILS_ENABLE_FAULT_INJECTION) 101 | endif() 102 | 103 | ament_add_gtest(test_service_type_support test/test_service_type_support_dispatch.cpp 104 | APPEND_ENV 105 | "DYLD_LIBRARY_PATH=${TEST_LIB_DIR}" 106 | "LD_LIBRARY_PATH=${TEST_LIB_DIR}" 107 | "PATH=${TEST_LIB_DIR}") 108 | ament_add_test_label(test_service_type_support mimick) 109 | if(TARGET test_service_type_support) 110 | target_link_libraries(test_service_type_support 111 | ${PROJECT_NAME} 112 | mimick 113 | rcpputils::rcpputils 114 | ) 115 | target_compile_definitions(test_service_type_support PUBLIC RCUTILS_ENABLE_FAULT_INJECTION) 116 | endif() 117 | 118 | # Test type_support_dispatch throws runtime error when trying to load this "library" 119 | file(GENERATE 120 | OUTPUT 121 | "${TEST_LIB_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}rosidl_typesupport_c__test_type_support3${CMAKE_SHARED_LIBRARY_SUFFIX}" 122 | CONTENT "I'm not a shared library, why would you treat me like one?") 123 | 124 | add_performance_test(benchmark_type_support_dispatch test/benchmark/benchmark_type_support_dispatch.cpp 125 | APPEND_ENV 126 | "DYLD_LIBRARY_PATH=${TEST_LIB_DIR}" 127 | "LD_LIBRARY_PATH=${TEST_LIB_DIR}" 128 | "PATH=${TEST_LIB_DIR}") 129 | if(TARGET benchmark_type_support_dispatch) 130 | target_link_libraries(benchmark_type_support_dispatch 131 | ${PROJECT_NAME} 132 | rcpputils::rcpputils) 133 | endif() 134 | 135 | find_package(ament_cmake_pytest REQUIRED) 136 | ament_add_pytest_test(test_cli_extension test/test_cli_extension.py) 137 | endif() 138 | 139 | if(BUILD_SHARED_LIBS) 140 | set(${PROJECT_NAME}_LIBRARY_TYPE "SHARED") 141 | else() 142 | set(${PROJECT_NAME}_LIBRARY_TYPE "STATIC") 143 | endif() 144 | 145 | ament_package( 146 | CONFIG_EXTRAS "rosidl_typesupport_c-extras.cmake.in" 147 | ) 148 | 149 | install( 150 | PROGRAMS bin/rosidl_typesupport_c 151 | DESTINATION lib/rosidl_typesupport_c 152 | ) 153 | install( 154 | DIRECTORY cmake resource 155 | DESTINATION share/${PROJECT_NAME} 156 | ) 157 | install( 158 | DIRECTORY include/ 159 | DESTINATION include/${PROJECT_NAME} 160 | ) 161 | install( 162 | TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME} 163 | ARCHIVE DESTINATION lib 164 | LIBRARY DESTINATION lib 165 | RUNTIME DESTINATION bin 166 | ) 167 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/resource/msg__type_support.cpp.em: -------------------------------------------------------------------------------- 1 | @# Included from rosidl_typesupport_c/resource/idl__type_support.c.em 2 | @{ 3 | from rosidl_generator_c import idl_structure_type_to_c_typename 4 | from rosidl_generator_type_description import GET_DESCRIPTION_FUNC 5 | from rosidl_generator_type_description import GET_HASH_FUNC 6 | from rosidl_generator_type_description import GET_SOURCES_FUNC 7 | from rosidl_pycommon import convert_camel_case_to_lower_case_underscore 8 | include_parts = [package_name] + list(interface_path.parents[0].parts) + [ 9 | 'detail', convert_camel_case_to_lower_case_underscore(interface_path.stem)] 10 | include_base = '/'.join(include_parts) 11 | 12 | header_files = [ 13 | 'cstddef', 14 | 'rosidl_runtime_c/message_type_support_struct.h', 15 | include_base + '__struct.h', 16 | include_base + '__type_support.h', 17 | include_base + '__functions.h', 18 | ] 19 | if len(type_supports) != 1: 20 | header_files += [ 21 | 'rosidl_typesupport_c/identifier.h', 22 | 'rosidl_typesupport_c/message_type_support_dispatch.h', 23 | 'rosidl_typesupport_c/type_support_map.h', 24 | ] 25 | header_files.append('rosidl_typesupport_c/visibility_control.h') 26 | if len(type_supports) != 1: 27 | header_files.append('rosidl_typesupport_interface/macros.h') 28 | }@ 29 | @[for header_file in header_files]@ 30 | @[ if header_file in include_directives]@ 31 | // already included above 32 | // @ 33 | @[ else]@ 34 | @{include_directives.add(header_file)}@ 35 | @[ end if]@ 36 | #include "@(header_file)" 37 | @[end for]@ 38 | @ 39 | @[if len(type_supports) != 1]@ 40 | @[ for ns in message.structure.namespaced_type.namespaces]@ 41 | 42 | namespace @(ns) 43 | { 44 | @[ end for]@ 45 | 46 | namespace rosidl_typesupport_c 47 | { 48 | 49 | typedef struct _@(message.structure.namespaced_type.name)_type_support_ids_t 50 | { 51 | const char * typesupport_identifier[@(len(type_supports))]; 52 | } _@(message.structure.namespaced_type.name)_type_support_ids_t; 53 | 54 | static const _@(message.structure.namespaced_type.name)_type_support_ids_t _@(message.structure.namespaced_type.name)_message_typesupport_ids = { 55 | { 56 | @# TODO(dirk-thomas) use identifier symbol again 57 | @[ for type_support in sorted(type_supports)]@ 58 | "@(type_support)", // ::@(type_support)::typesupport_identifier, 59 | @[ end for]@ 60 | } 61 | }; 62 | 63 | typedef struct _@(message.structure.namespaced_type.name)_type_support_symbol_names_t 64 | { 65 | const char * symbol_name[@(len(type_supports))]; 66 | } _@(message.structure.namespaced_type.name)_type_support_symbol_names_t; 67 | 68 | #define STRINGIFY_(s) #s 69 | #define STRINGIFY(s) STRINGIFY_(s) 70 | 71 | static const _@(message.structure.namespaced_type.name)_type_support_symbol_names_t _@(message.structure.namespaced_type.name)_message_typesupport_symbol_names = { 72 | { 73 | @[ for type_support in sorted(type_supports)]@ 74 | STRINGIFY(ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(@(type_support), @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(message.structure.namespaced_type.name))), 75 | @[ end for]@ 76 | } 77 | }; 78 | 79 | typedef struct _@(message.structure.namespaced_type.name)_type_support_data_t 80 | { 81 | void * data[@(len(type_supports))]; 82 | } _@(message.structure.namespaced_type.name)_type_support_data_t; 83 | 84 | static _@(message.structure.namespaced_type.name)_type_support_data_t _@(message.structure.namespaced_type.name)_message_typesupport_data = { 85 | { 86 | @[for type_support in sorted(type_supports)]@ 87 | 0, // will store the shared library later 88 | @[end for]@ 89 | } 90 | }; 91 | 92 | static const type_support_map_t _@(message.structure.namespaced_type.name)_message_typesupport_map = { 93 | @(len(type_supports)), 94 | "@(package_name)", 95 | &_@(message.structure.namespaced_type.name)_message_typesupport_ids.typesupport_identifier[0], 96 | &_@(message.structure.namespaced_type.name)_message_typesupport_symbol_names.symbol_name[0], 97 | &_@(message.structure.namespaced_type.name)_message_typesupport_data.data[0], 98 | }; 99 | 100 | static const rosidl_message_type_support_t @(message.structure.namespaced_type.name)_message_type_support_handle = { 101 | rosidl_typesupport_c__typesupport_identifier, 102 | reinterpret_cast(&_@(message.structure.namespaced_type.name)_message_typesupport_map), 103 | rosidl_typesupport_c__get_message_typesupport_handle_function, 104 | &@(idl_structure_type_to_c_typename(message.structure.namespaced_type))__@(GET_HASH_FUNC), 105 | &@(idl_structure_type_to_c_typename(message.structure.namespaced_type))__@(GET_DESCRIPTION_FUNC), 106 | &@(idl_structure_type_to_c_typename(message.structure.namespaced_type))__@(GET_SOURCES_FUNC), 107 | }; 108 | 109 | } // namespace rosidl_typesupport_c 110 | @[ for ns in reversed(message.structure.namespaced_type.namespaces)]@ 111 | 112 | } // namespace @(ns) 113 | @[ end for]@ 114 | 115 | @[else]@ 116 | @{ 117 | include_parts = [package_name] + list(interface_path.parents[0].parts) + [ 118 | 'detail', convert_camel_case_to_lower_case_underscore(interface_path.stem)] 119 | include_base = '/'.join(include_parts) 120 | header_file = include_base + '__' + list(type_supports)[0] + '.h' 121 | }@ 122 | @[ if header_file in include_directives]@ 123 | // already included above 124 | // @ 125 | @[ else]@ 126 | @{include_directives.add(header_file)}@ 127 | @[ end if]@ 128 | #include "@(header_file)" 129 | 130 | @[end if]@ 131 | #ifdef __cplusplus 132 | extern "C" 133 | { 134 | #endif 135 | 136 | const rosidl_message_type_support_t * 137 | ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_c, @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(message.structure.namespaced_type.name))() { 138 | @[if len(type_supports) != 1]@ 139 | return &::@('::'.join([package_name] + list(interface_path.parents[0].parts)))::rosidl_typesupport_c::@(message.structure.namespaced_type.name)_message_type_support_handle; 140 | @[else]@ 141 | return ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(@(list(type_supports)[0]), @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(message.structure.namespaced_type.name))(); 142 | @[end if]@ 143 | } 144 | 145 | #ifdef __cplusplus 146 | } 147 | #endif 148 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/test/test_service_type_support_dispatch.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include "rcutils/error_handling.h" 17 | #include "rcutils/testing/fault_injection.h" 18 | #include "rcpputils/shared_library.hpp" 19 | #include "rosidl_typesupport_c/type_support_map.h" 20 | #include "rosidl_typesupport_cpp/identifier.hpp" 21 | #include "rosidl_typesupport_cpp/service_type_support_dispatch.hpp" 22 | 23 | constexpr size_t map_size = 4u; 24 | constexpr const char package_name[] = "rosidl_typesupport_cpp"; 25 | constexpr const char * identifiers[map_size] = { 26 | "test_type_support1", "test_type_support2", "test_type_support3", "test_type_support4" 27 | }; 28 | 29 | constexpr const char * symbols[map_size] = { 30 | "test_service_type_support", 31 | "test_service_type_support2", 32 | "test_service_type_support3", 33 | "test_service_type_support4" 34 | }; 35 | 36 | rosidl_service_type_support_t get_rosidl_service_type_support(const char * identifier) 37 | { 38 | return { 39 | identifier, 40 | nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr 41 | }; 42 | } 43 | 44 | type_support_map_t get_typesupport_map(void ** library_array) 45 | { 46 | return type_support_map_t{ 47 | map_size, 48 | package_name, 49 | identifiers, 50 | symbols, 51 | library_array, 52 | }; 53 | } 54 | 55 | TEST(TestServiceTypeSupportDispatch, get_handle_function) { 56 | // Both arguments are nullptrs 57 | EXPECT_DEATH( 58 | rosidl_typesupport_cpp::get_service_typesupport_handle_function(nullptr, nullptr), ""); 59 | 60 | // Handle is a nullptr 61 | EXPECT_DEATH( 62 | rosidl_typesupport_cpp::get_service_typesupport_handle_function( 63 | nullptr, 64 | "identifier"), ""); 65 | 66 | // Handle's identifier is a nullptr 67 | rosidl_service_type_support_t null_type_support = get_rosidl_service_type_support(nullptr); 68 | EXPECT_DEATH( 69 | rosidl_typesupport_cpp::get_service_typesupport_handle_function( 70 | &null_type_support, 71 | "identifier"), ""); 72 | 73 | // Identifier is a nullptr 74 | rosidl_service_type_support_t type_support = get_rosidl_service_type_support("identifier"); 75 | EXPECT_DEATH( 76 | rosidl_typesupport_cpp::get_service_typesupport_handle_function( 77 | &type_support, 78 | nullptr), ""); 79 | 80 | // Identifier matches this handle's identifier 81 | EXPECT_EQ( 82 | rosidl_typesupport_cpp::get_service_typesupport_handle_function( 83 | &type_support, 84 | "identifier"), &type_support); 85 | 86 | // Identifier is not the same and isn't the rosidl_typesupport_cpp__typesupport_identifier 87 | EXPECT_EQ( 88 | rosidl_typesupport_cpp::get_service_typesupport_handle_function( 89 | &type_support, 90 | "different_identifier"), nullptr); 91 | EXPECT_TRUE(rcutils_error_is_set()); 92 | rcutils_reset_error(); 93 | 94 | rosidl_service_type_support_t type_support_cpp_identifier = 95 | get_rosidl_service_type_support(rosidl_typesupport_cpp::typesupport_identifier); 96 | rcpputils::SharedLibrary * library_array[map_size] = {nullptr, nullptr, nullptr}; 97 | type_support_map_t support_map = get_typesupport_map(reinterpret_cast(&library_array)); 98 | type_support_cpp_identifier.data = &support_map; 99 | 100 | // Successfully load library and find symbols 101 | auto * result = rosidl_typesupport_cpp::get_service_typesupport_handle_function( 102 | &type_support_cpp_identifier, 103 | "test_type_support1"); 104 | ASSERT_NE(result, nullptr); 105 | ASSERT_NE(support_map.data[0], nullptr); 106 | auto * clib = static_cast(support_map.data[0]); 107 | auto * lib = const_cast(clib); 108 | ASSERT_NE(lib, nullptr); 109 | 110 | EXPECT_TRUE(lib->has_symbol("test_service_type_support")); 111 | auto * sym = lib->get_symbol("test_service_type_support"); 112 | ASSERT_NE(sym, nullptr); 113 | 114 | // Loads library, but symbol doesn't exist 115 | EXPECT_EQ( 116 | rosidl_typesupport_cpp::get_service_typesupport_handle_function( 117 | &type_support_cpp_identifier, 118 | "test_type_support2"), nullptr); 119 | EXPECT_TRUE(rcutils_error_is_set()); 120 | rcutils_reset_error(); 121 | 122 | // Library file exists, but loading shared library fails 123 | EXPECT_EQ( 124 | rosidl_typesupport_cpp::get_service_typesupport_handle_function( 125 | &type_support_cpp_identifier, 126 | "test_type_support3"), nullptr); 127 | EXPECT_TRUE(rcutils_error_is_set()); 128 | rcutils_reset_error(); 129 | 130 | // Library doesn't exist 131 | EXPECT_EQ( 132 | rosidl_typesupport_cpp::get_service_typesupport_handle_function( 133 | &type_support_cpp_identifier, 134 | "test_type_support4"), nullptr); 135 | EXPECT_TRUE(rcutils_error_is_set()); 136 | rcutils_reset_error(); 137 | } 138 | 139 | TEST(TestServiceTypeSupportDispatch, get_service_typesupport_maybe_fail_test) 140 | { 141 | rosidl_service_type_support_t type_support_cpp_identifier = 142 | get_rosidl_service_type_support(rosidl_typesupport_cpp::typesupport_identifier); 143 | rcpputils::SharedLibrary * library_array[map_size] = {nullptr, nullptr, nullptr}; 144 | type_support_map_t support_map = get_typesupport_map(reinterpret_cast(&library_array)); 145 | type_support_cpp_identifier.data = &support_map; 146 | 147 | RCUTILS_FAULT_INJECTION_TEST( 148 | { 149 | // load library and find symbols 150 | auto * result = rosidl_typesupport_cpp::get_service_typesupport_handle_function( 151 | &type_support_cpp_identifier, 152 | "test_type_support1"); 153 | if (nullptr == result) { 154 | EXPECT_TRUE(rcutils_error_is_set()); 155 | rcutils_reset_error(); 156 | } 157 | }); 158 | } 159 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/test/test_message_type_support_dispatch.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include "rcutils/error_handling.h" 17 | #include "rcutils/testing/fault_injection.h" 18 | #include "rcpputils/shared_library.hpp" 19 | #include "rosidl_typesupport_c/type_support_map.h" 20 | #include "rosidl_typesupport_cpp/identifier.hpp" 21 | #include "rosidl_typesupport_cpp/message_type_support_dispatch.hpp" 22 | 23 | constexpr size_t map_size = 4u; 24 | constexpr const char package_name[] = "rosidl_typesupport_cpp"; 25 | constexpr const char * identifiers[map_size] = { 26 | "test_type_support1", "test_type_support2", "test_type_support3", "test_type_support4" 27 | }; 28 | 29 | constexpr const char * symbols[map_size] = { 30 | "test_message_type_support", 31 | "test_message_type_support2", 32 | "test_message_type_support3", 33 | "test_message_type_support4" 34 | }; 35 | 36 | rosidl_message_type_support_t get_rosidl_message_type_support(const char * identifier) 37 | { 38 | return {identifier, nullptr, nullptr, nullptr, nullptr, nullptr}; 39 | } 40 | 41 | type_support_map_t get_typesupport_map(void ** library_array) 42 | { 43 | return type_support_map_t{ 44 | map_size, 45 | package_name, 46 | identifiers, 47 | symbols, 48 | library_array, 49 | }; 50 | } 51 | 52 | TEST(TestMessageTypeSupportDispatch, get_handle_function) { 53 | // Both arguments are nullptrs 54 | EXPECT_DEATH( 55 | rosidl_typesupport_cpp::get_message_typesupport_handle_function(nullptr, nullptr), ""); 56 | 57 | // Handle is a nullptr 58 | EXPECT_DEATH( 59 | rosidl_typesupport_cpp::get_message_typesupport_handle_function( 60 | nullptr, 61 | "identifier"), ""); 62 | 63 | // Handle's identifier is a nullptr 64 | rosidl_message_type_support_t null_type_support = get_rosidl_message_type_support(nullptr); 65 | EXPECT_DEATH( 66 | rosidl_typesupport_cpp::get_message_typesupport_handle_function( 67 | &null_type_support, 68 | "identifier"), ""); 69 | 70 | // Identifier is a nullptr 71 | rosidl_message_type_support_t type_support = get_rosidl_message_type_support("identifier"); 72 | EXPECT_DEATH( 73 | rosidl_typesupport_cpp::get_message_typesupport_handle_function( 74 | &type_support, 75 | nullptr), ""); 76 | 77 | // Identifier matches this handle's identifier 78 | EXPECT_EQ( 79 | rosidl_typesupport_cpp::get_message_typesupport_handle_function( 80 | &type_support, 81 | "identifier"), &type_support); 82 | 83 | // Identifier is not the same and isn't the rosidl_typesupport_cpp__typesupport_identifier 84 | EXPECT_EQ( 85 | rosidl_typesupport_cpp::get_message_typesupport_handle_function( 86 | &type_support, 87 | "different_identifier"), nullptr); 88 | EXPECT_TRUE(rcutils_error_is_set()); 89 | rcutils_reset_error(); 90 | 91 | rosidl_message_type_support_t type_support_cpp_identifier = 92 | get_rosidl_message_type_support(rosidl_typesupport_cpp::typesupport_identifier); 93 | rcpputils::SharedLibrary * library_array[map_size] = {nullptr, nullptr, nullptr}; 94 | type_support_map_t support_map = get_typesupport_map(reinterpret_cast(&library_array)); 95 | type_support_cpp_identifier.data = &support_map; 96 | 97 | // Successfully load library and find symbols 98 | auto * result = rosidl_typesupport_cpp::get_message_typesupport_handle_function( 99 | &type_support_cpp_identifier, 100 | "test_type_support1"); 101 | ASSERT_NE(result, nullptr); 102 | ASSERT_NE(support_map.data[0], nullptr); 103 | auto * clib = static_cast(support_map.data[0]); 104 | auto * lib = const_cast(clib); 105 | ASSERT_NE(lib, nullptr); 106 | 107 | EXPECT_TRUE(lib->has_symbol("test_message_type_support")); 108 | auto * sym = lib->get_symbol("test_message_type_support"); 109 | ASSERT_NE(sym, nullptr); 110 | if (library_array[0] != nullptr) { 111 | delete library_array[0]; 112 | } 113 | 114 | // Loads library, but symbol doesn't exist 115 | EXPECT_EQ( 116 | rosidl_typesupport_cpp::get_message_typesupport_handle_function( 117 | &type_support_cpp_identifier, 118 | "test_type_support2"), nullptr); 119 | EXPECT_TRUE(rcutils_error_is_set()); 120 | rcutils_reset_error(); 121 | 122 | // Library file exists, but loading shared library fails 123 | EXPECT_EQ( 124 | rosidl_typesupport_cpp::get_message_typesupport_handle_function( 125 | &type_support_cpp_identifier, 126 | "test_type_support3"), nullptr); 127 | EXPECT_TRUE(rcutils_error_is_set()); 128 | rcutils_reset_error(); 129 | 130 | // Library doesn't exist 131 | EXPECT_EQ( 132 | rosidl_typesupport_cpp::get_message_typesupport_handle_function( 133 | &type_support_cpp_identifier, 134 | "test_type_support4"), nullptr); 135 | EXPECT_TRUE(rcutils_error_is_set()); 136 | rcutils_reset_error(); 137 | } 138 | 139 | TEST(TestMessageTypeSupportDispatch, get_message_typesupport_maybe_fail_test) 140 | { 141 | rosidl_message_type_support_t type_support_cpp_identifier = 142 | get_rosidl_message_type_support(rosidl_typesupport_cpp::typesupport_identifier); 143 | rcpputils::SharedLibrary * library_array[map_size] = {nullptr, nullptr, nullptr}; 144 | type_support_map_t support_map = get_typesupport_map(reinterpret_cast(&library_array)); 145 | type_support_cpp_identifier.data = &support_map; 146 | 147 | RCUTILS_FAULT_INJECTION_TEST( 148 | { 149 | // load library and find symbols 150 | auto * result = rosidl_typesupport_cpp::get_message_typesupport_handle_function( 151 | &type_support_cpp_identifier, 152 | "test_type_support1"); 153 | if (nullptr == result) { 154 | EXPECT_TRUE(rcutils_error_is_set()); 155 | rcutils_reset_error(); 156 | } 157 | }); 158 | } 159 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/test/test_message_type_support_dispatch.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | #include "rcpputils/shared_library.hpp" 18 | #include "rcutils/error_handling.h" 19 | #include "rcutils/testing/fault_injection.h" 20 | #include "rosidl_typesupport_c/identifier.h" 21 | #include "rosidl_typesupport_c/message_type_support_dispatch.h" 22 | #include "rosidl_typesupport_c/type_support_map.h" 23 | 24 | #include "./mocking_utils/patch.hpp" 25 | 26 | constexpr size_t map_size = 4u; 27 | constexpr const char package_name[] = "rosidl_typesupport_c"; 28 | constexpr const char * identifiers[map_size] = { 29 | "test_type_support1", "test_type_support2", "test_type_support3", "test_type_support4" 30 | }; 31 | 32 | constexpr const char * symbols[map_size] = { 33 | "test_message_type_support", 34 | "test_message_type_support2", 35 | "test_message_type_support3", 36 | "test_message_type_support4" 37 | }; 38 | 39 | rosidl_message_type_support_t get_rosidl_message_type_support(const char * identifier) 40 | { 41 | return {identifier, nullptr, nullptr, nullptr, nullptr, nullptr}; 42 | } 43 | 44 | type_support_map_t get_typesupport_map(void ** library_array) 45 | { 46 | return type_support_map_t{ 47 | map_size, 48 | package_name, 49 | identifiers, 50 | symbols, 51 | library_array, 52 | }; 53 | } 54 | 55 | TEST(TestMessageTypeSupportDispatch, get_handle_function) { 56 | // Both arguments are nullptrs 57 | EXPECT_DEATH( 58 | rosidl_typesupport_c__get_message_typesupport_handle_function(nullptr, nullptr), ""); 59 | 60 | // Handle is a nullptr 61 | EXPECT_DEATH( 62 | rosidl_typesupport_c__get_message_typesupport_handle_function( 63 | nullptr, 64 | "identifier"), ""); 65 | 66 | // Handle's identifier is a nullptr 67 | rosidl_message_type_support_t null_type_support = get_rosidl_message_type_support(nullptr); 68 | EXPECT_DEATH( 69 | rosidl_typesupport_c__get_message_typesupport_handle_function( 70 | &null_type_support, 71 | "identifier"), ""); 72 | 73 | // Identifier is a nullptr 74 | rosidl_message_type_support_t type_support = get_rosidl_message_type_support("identifier"); 75 | EXPECT_DEATH( 76 | rosidl_typesupport_c__get_message_typesupport_handle_function( 77 | &type_support, 78 | nullptr), ""); 79 | 80 | // Identifier matches this handle's identifier 81 | EXPECT_EQ( 82 | rosidl_typesupport_c__get_message_typesupport_handle_function( 83 | &type_support, 84 | "identifier"), &type_support); 85 | 86 | // Identifier is not the same and isn't the rosidl_typesupport_c__typesupport_identifier 87 | EXPECT_EQ( 88 | rosidl_typesupport_c__get_message_typesupport_handle_function( 89 | &type_support, 90 | "different_identifier"), nullptr); 91 | EXPECT_TRUE(rcutils_error_is_set()); 92 | rcutils_reset_error(); 93 | 94 | rosidl_message_type_support_t type_support_c_identifier = 95 | get_rosidl_message_type_support(rosidl_typesupport_c__typesupport_identifier); 96 | rcpputils::SharedLibrary * library_array[map_size] = {nullptr, nullptr, nullptr}; 97 | type_support_map_t support_map = get_typesupport_map(reinterpret_cast(&library_array)); 98 | type_support_c_identifier.data = &support_map; 99 | 100 | { 101 | // rcutils_get_symbol fails (after rcutils_has_symbol succeeds) 102 | auto mock = mocking_utils::patch_and_return("lib:rcpputils", rcutils_get_symbol, nullptr); 103 | EXPECT_EQ( 104 | rosidl_typesupport_c__get_message_typesupport_handle_function( 105 | &type_support_c_identifier, 106 | "test_type_support1"), nullptr); 107 | rcutils_reset_error(); 108 | } 109 | 110 | // Successfully load library and find symbols 111 | auto * result = rosidl_typesupport_c__get_message_typesupport_handle_function( 112 | &type_support_c_identifier, 113 | "test_type_support1"); 114 | ASSERT_NE(result, nullptr); 115 | ASSERT_NE(support_map.data[0], nullptr); 116 | auto * clib = static_cast(support_map.data[0]); 117 | auto * lib = const_cast(clib); 118 | ASSERT_TRUE(nullptr != lib); 119 | 120 | EXPECT_TRUE(lib->has_symbol("test_message_type_support")); 121 | auto * sym = lib->get_symbol("test_message_type_support"); 122 | ASSERT_NE(sym, nullptr); 123 | 124 | // Loads library, but symbol doesn't exist 125 | EXPECT_EQ( 126 | rosidl_typesupport_c__get_message_typesupport_handle_function( 127 | &type_support_c_identifier, 128 | "test_type_support2"), nullptr); 129 | EXPECT_TRUE(rcutils_error_is_set()); 130 | rcutils_reset_error(); 131 | 132 | // Library file exists, but loading shared library fails 133 | EXPECT_EQ( 134 | rosidl_typesupport_c__get_message_typesupport_handle_function( 135 | &type_support_c_identifier, 136 | "test_type_support3"), nullptr); 137 | EXPECT_TRUE(rcutils_error_is_set()); 138 | rcutils_reset_error(); 139 | 140 | // Library doesn't exist 141 | EXPECT_EQ( 142 | rosidl_typesupport_c__get_message_typesupport_handle_function( 143 | &type_support_c_identifier, 144 | "test_type_support4"), nullptr); 145 | EXPECT_TRUE(rcutils_error_is_set()); 146 | rcutils_reset_error(); 147 | } 148 | 149 | TEST(TestMessageTypeSupportDispatch, get_message_typesupport_maybe_fail_test) 150 | { 151 | rosidl_message_type_support_t type_support_c_identifier = 152 | get_rosidl_message_type_support(rosidl_typesupport_c__typesupport_identifier); 153 | rcpputils::SharedLibrary * library_array[map_size] = {nullptr, nullptr, nullptr}; 154 | type_support_map_t support_map = get_typesupport_map(reinterpret_cast(&library_array)); 155 | type_support_c_identifier.data = &support_map; 156 | 157 | RCUTILS_FAULT_INJECTION_TEST( 158 | { 159 | auto * result = rosidl_typesupport_c__get_message_typesupport_handle_function( 160 | &type_support_c_identifier, 161 | "test_type_support1"); 162 | if (nullptr == result) { 163 | EXPECT_TRUE(rcutils_error_is_set()); 164 | rcutils_reset_error(); 165 | } 166 | }); 167 | } 168 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/test/test_service_type_support_dispatch.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | #include "rcpputils/shared_library.hpp" 18 | #include "rcutils/error_handling.h" 19 | #include "rcutils/testing/fault_injection.h" 20 | #include "rosidl_typesupport_c/identifier.h" 21 | #include "rosidl_typesupport_c/service_type_support_dispatch.h" 22 | #include "rosidl_typesupport_c/type_support_map.h" 23 | 24 | #include "./mocking_utils/patch.hpp" 25 | 26 | constexpr size_t map_size = 4u; 27 | constexpr const char package_name[] = "rosidl_typesupport_c"; 28 | constexpr const char * identifiers[map_size] = { 29 | "test_type_support1", "test_type_support2", "test_type_support3", "test_type_support4" 30 | }; 31 | 32 | constexpr const char * symbols[map_size] = { 33 | "test_service_type_support", 34 | "test_service_type_support2", 35 | "test_service_type_support3", 36 | "test_service_type_support4" 37 | }; 38 | 39 | rosidl_service_type_support_t get_rosidl_service_type_support(const char * identifier) 40 | { 41 | return { 42 | identifier, 43 | nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr 44 | }; 45 | } 46 | 47 | type_support_map_t get_typesupport_map(void ** library_array) 48 | { 49 | return type_support_map_t{ 50 | map_size, 51 | package_name, 52 | identifiers, 53 | symbols, 54 | library_array, 55 | }; 56 | } 57 | 58 | TEST(TestServiceTypeSupportDispatch, get_handle_function) { 59 | // Both arguments are nullptrs 60 | EXPECT_DEATH( 61 | rosidl_typesupport_c__get_service_typesupport_handle_function(nullptr, nullptr), ""); 62 | 63 | // Handle is a nullptr 64 | EXPECT_DEATH( 65 | rosidl_typesupport_c__get_service_typesupport_handle_function( 66 | nullptr, 67 | "identifier"), ""); 68 | 69 | // Handle's identifier is a nullptr 70 | rosidl_service_type_support_t null_type_support = get_rosidl_service_type_support(nullptr); 71 | EXPECT_DEATH( 72 | rosidl_typesupport_c__get_service_typesupport_handle_function( 73 | &null_type_support, 74 | "identifier"), ""); 75 | 76 | // Identifier is a nullptr 77 | rosidl_service_type_support_t type_support = get_rosidl_service_type_support("identifier"); 78 | EXPECT_DEATH( 79 | rosidl_typesupport_c__get_service_typesupport_handle_function( 80 | &type_support, 81 | nullptr), ""); 82 | 83 | // Identifier matches this handle's identifier 84 | EXPECT_EQ( 85 | rosidl_typesupport_c__get_service_typesupport_handle_function( 86 | &type_support, 87 | "identifier"), &type_support); 88 | 89 | // Identifier is not the same and isn't the rosidl_typesupport_c__typesupport_identifier 90 | EXPECT_EQ( 91 | rosidl_typesupport_c__get_service_typesupport_handle_function( 92 | &type_support, 93 | "different_identifier"), nullptr); 94 | EXPECT_TRUE(rcutils_error_is_set()); 95 | rcutils_reset_error(); 96 | 97 | rosidl_service_type_support_t type_support_c_identifier = 98 | get_rosidl_service_type_support(rosidl_typesupport_c__typesupport_identifier); 99 | rcpputils::SharedLibrary * library_array[map_size] = {nullptr, nullptr, nullptr}; 100 | type_support_map_t support_map = get_typesupport_map(reinterpret_cast(&library_array)); 101 | type_support_c_identifier.data = &support_map; 102 | 103 | { 104 | // rcutils_get_symbol fails (after rcutils_has_symbol succeeds) 105 | auto mock = mocking_utils::patch_and_return("lib:rcpputils", rcutils_get_symbol, nullptr); 106 | EXPECT_EQ( 107 | rosidl_typesupport_c__get_service_typesupport_handle_function( 108 | &type_support_c_identifier, 109 | "test_type_support1"), nullptr); 110 | rcutils_reset_error(); 111 | } 112 | 113 | // Successfully load library and find symbols 114 | auto * result = rosidl_typesupport_c__get_service_typesupport_handle_function( 115 | &type_support_c_identifier, 116 | "test_type_support1"); 117 | ASSERT_NE(result, nullptr); 118 | ASSERT_NE(support_map.data[0], nullptr); 119 | auto * clib = static_cast(support_map.data[0]); 120 | auto * lib = const_cast(clib); 121 | ASSERT_TRUE(nullptr != lib); 122 | 123 | EXPECT_TRUE(lib->has_symbol("test_service_type_support")); 124 | auto * sym = lib->get_symbol("test_service_type_support"); 125 | ASSERT_NE(sym, nullptr); 126 | 127 | // Loads library, but symbol doesn't exist 128 | EXPECT_EQ( 129 | rosidl_typesupport_c__get_service_typesupport_handle_function( 130 | &type_support_c_identifier, 131 | "test_type_support2"), nullptr); 132 | EXPECT_TRUE(rcutils_error_is_set()); 133 | rcutils_reset_error(); 134 | 135 | // Library file exists, but loading shared library fails 136 | EXPECT_EQ( 137 | rosidl_typesupport_c__get_service_typesupport_handle_function( 138 | &type_support_c_identifier, 139 | "test_type_support3"), nullptr); 140 | EXPECT_TRUE(rcutils_error_is_set()); 141 | rcutils_reset_error(); 142 | 143 | // Library doesn't exist 144 | EXPECT_EQ( 145 | rosidl_typesupport_c__get_service_typesupport_handle_function( 146 | &type_support_c_identifier, 147 | "test_type_support4"), nullptr); 148 | EXPECT_TRUE(rcutils_error_is_set()); 149 | rcutils_reset_error(); 150 | } 151 | 152 | TEST(TestServiceTypeSupportDispatch, get_service_typesupport_maybe_fail_test) 153 | { 154 | rosidl_service_type_support_t type_support_c_identifier = 155 | get_rosidl_service_type_support(rosidl_typesupport_c__typesupport_identifier); 156 | rcpputils::SharedLibrary * library_array[map_size] = {nullptr, nullptr, nullptr}; 157 | type_support_map_t support_map = get_typesupport_map(reinterpret_cast(&library_array)); 158 | type_support_c_identifier.data = &support_map; 159 | 160 | RCUTILS_FAULT_INJECTION_TEST( 161 | { 162 | auto * result = rosidl_typesupport_c__get_service_typesupport_handle_function( 163 | &type_support_c_identifier, 164 | "test_type_support1"); 165 | if (nullptr == result) { 166 | EXPECT_TRUE(rcutils_error_is_set()); 167 | rcutils_reset_error(); 168 | } 169 | }); 170 | } 171 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/resource/msg__type_support.cpp.em: -------------------------------------------------------------------------------- 1 | @# Included from rosidl_typesupport_cpp/resource/idl__type_support.cpp.em 2 | @{ 3 | from rosidl_generator_c import idl_structure_type_to_c_typename 4 | from rosidl_generator_type_description import GET_DESCRIPTION_FUNC 5 | from rosidl_generator_type_description import GET_HASH_FUNC 6 | from rosidl_generator_type_description import GET_SOURCES_FUNC 7 | from rosidl_pycommon import convert_camel_case_to_lower_case_underscore 8 | include_parts = [package_name] + list(interface_path.parents[0].parts) + [ 9 | 'detail', convert_camel_case_to_lower_case_underscore(interface_path.stem)] 10 | include_base = '/'.join(include_parts) 11 | 12 | header_files = [ 13 | 'cstddef', 14 | 'rosidl_runtime_c/message_type_support_struct.h', 15 | include_base + '__functions.h', 16 | include_base + '__struct.hpp', 17 | ] 18 | if len(type_supports) != 1: 19 | header_files.append('rosidl_typesupport_cpp/identifier.hpp') 20 | header_files.append('rosidl_typesupport_cpp/message_type_support.hpp') 21 | if len(type_supports) != 1: 22 | header_files += [ 23 | 'rosidl_typesupport_c/type_support_map.h', 24 | 'rosidl_typesupport_cpp/message_type_support_dispatch.hpp', 25 | ] 26 | header_files.append('rosidl_typesupport_cpp/visibility_control.h') 27 | if len(type_supports) != 1: 28 | header_files.append('rosidl_typesupport_interface/macros.h') 29 | }@ 30 | @[for header_file in header_files]@ 31 | @[ if header_file in include_directives]@ 32 | // already included above 33 | // @ 34 | @[ else]@ 35 | @{include_directives.add(header_file)}@ 36 | @[ end if]@ 37 | #include "@(header_file)" 38 | @[end for]@ 39 | @ 40 | @[if len(type_supports) != 1]@ 41 | @[ for ns in message.structure.namespaced_type.namespaces]@ 42 | 43 | namespace @(ns) 44 | { 45 | @[ end for]@ 46 | 47 | namespace rosidl_typesupport_cpp 48 | { 49 | 50 | typedef struct _@(message.structure.namespaced_type.name)_type_support_ids_t 51 | { 52 | const char * typesupport_identifier[@(len(type_supports))]; 53 | } _@(message.structure.namespaced_type.name)_type_support_ids_t; 54 | 55 | static const _@(message.structure.namespaced_type.name)_type_support_ids_t _@(message.structure.namespaced_type.name)_message_typesupport_ids = { 56 | { 57 | @# TODO(dirk-thomas) use identifier symbol again 58 | @[for type_support in sorted(type_supports)]@ 59 | "@(type_support)", // ::@(type_support)::typesupport_identifier, 60 | @[end for]@ 61 | } 62 | }; 63 | 64 | typedef struct _@(message.structure.namespaced_type.name)_type_support_symbol_names_t 65 | { 66 | const char * symbol_name[@(len(type_supports))]; 67 | } _@(message.structure.namespaced_type.name)_type_support_symbol_names_t; 68 | 69 | #define STRINGIFY_(s) #s 70 | #define STRINGIFY(s) STRINGIFY_(s) 71 | 72 | static const _@(message.structure.namespaced_type.name)_type_support_symbol_names_t _@(message.structure.namespaced_type.name)_message_typesupport_symbol_names = { 73 | { 74 | @[for type_support in sorted(type_supports)]@ 75 | STRINGIFY(ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(@(type_support), @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(message.structure.namespaced_type.name))), 76 | @[end for]@ 77 | } 78 | }; 79 | 80 | typedef struct _@(message.structure.namespaced_type.name)_type_support_data_t 81 | { 82 | void * data[@(len(type_supports))]; 83 | } _@(message.structure.namespaced_type.name)_type_support_data_t; 84 | 85 | static _@(message.structure.namespaced_type.name)_type_support_data_t _@(message.structure.namespaced_type.name)_message_typesupport_data = { 86 | { 87 | @[for type_support in sorted(type_supports)]@ 88 | 0, // will store the shared library later 89 | @[end for]@ 90 | } 91 | }; 92 | 93 | static const type_support_map_t _@(message.structure.namespaced_type.name)_message_typesupport_map = { 94 | @(len(type_supports)), 95 | "@(package_name)", 96 | &_@(message.structure.namespaced_type.name)_message_typesupport_ids.typesupport_identifier[0], 97 | &_@(message.structure.namespaced_type.name)_message_typesupport_symbol_names.symbol_name[0], 98 | &_@(message.structure.namespaced_type.name)_message_typesupport_data.data[0], 99 | }; 100 | 101 | static const rosidl_message_type_support_t @(message.structure.namespaced_type.name)_message_type_support_handle = { 102 | ::rosidl_typesupport_cpp::typesupport_identifier, 103 | reinterpret_cast(&_@(message.structure.namespaced_type.name)_message_typesupport_map), 104 | ::rosidl_typesupport_cpp::get_message_typesupport_handle_function, 105 | &@(idl_structure_type_to_c_typename(message.structure.namespaced_type))__@(GET_HASH_FUNC), 106 | &@(idl_structure_type_to_c_typename(message.structure.namespaced_type))__@(GET_DESCRIPTION_FUNC), 107 | &@(idl_structure_type_to_c_typename(message.structure.namespaced_type))__@(GET_SOURCES_FUNC), 108 | }; 109 | 110 | } // namespace rosidl_typesupport_cpp 111 | @[ for ns in reversed(message.structure.namespaced_type.namespaces)]@ 112 | 113 | } // namespace @(ns) 114 | @[ end for]@ 115 | 116 | @[else]@ 117 | @{ 118 | include_parts = [package_name] + list(interface_path.parents[0].parts) + [ 119 | 'detail', convert_camel_case_to_lower_case_underscore(interface_path.stem)] 120 | include_base = '/'.join(include_parts) 121 | header_file = include_base + '__' + list(type_supports)[0] + '.hpp' 122 | }@ 123 | @[ if header_file in include_directives]@ 124 | // already included above 125 | // @ 126 | @[ else]@ 127 | @{include_directives.add(header_file)}@ 128 | @[ end if]@ 129 | #include "@(header_file)" 130 | 131 | @[end if]@ 132 | namespace rosidl_typesupport_cpp 133 | { 134 | 135 | template<> 136 | ROSIDL_TYPESUPPORT_CPP_PUBLIC 137 | const rosidl_message_type_support_t * 138 | get_message_type_support_handle<@('::'.join([package_name] + list(interface_path.parents[0].parts)))::@(message.structure.namespaced_type.name)>() 139 | { 140 | @[if len(type_supports) != 1]@ 141 | return &::@('::'.join([package_name] + list(interface_path.parents[0].parts)))::rosidl_typesupport_cpp::@(message.structure.namespaced_type.name)_message_type_support_handle; 142 | @[else]@ 143 | return ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(@(list(type_supports)[0]), @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(message.structure.namespaced_type.name))(); 144 | @[end if]@ 145 | } 146 | 147 | #ifdef __cplusplus 148 | extern "C" 149 | { 150 | #endif 151 | 152 | ROSIDL_TYPESUPPORT_CPP_PUBLIC 153 | const rosidl_message_type_support_t * 154 | ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_cpp, @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(message.structure.namespaced_type.name))() { 155 | return get_message_type_support_handle<@('::'.join([package_name] + list(interface_path.parents[0].parts)))::@(message.structure.namespaced_type.name)>(); 156 | } 157 | 158 | #ifdef __cplusplus 159 | } 160 | #endif 161 | } // namespace rosidl_typesupport_cpp 162 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/resource/srv__type_support.cpp.em: -------------------------------------------------------------------------------- 1 | @# Included from rosidl_typesupport_c/resource/idl__type_support.c.em 2 | @{ 3 | TEMPLATE( 4 | 'msg__type_support.cpp.em', 5 | package_name=package_name, interface_path=interface_path, 6 | message=service.request_message, include_directives=include_directives, 7 | type_supports=type_supports) 8 | }@ 9 | 10 | @{ 11 | TEMPLATE( 12 | 'msg__type_support.cpp.em', 13 | package_name=package_name, interface_path=interface_path, 14 | message=service.response_message, include_directives=include_directives, 15 | type_supports=type_supports) 16 | }@ 17 | 18 | @{ 19 | TEMPLATE( 20 | 'msg__type_support.cpp.em', 21 | package_name=package_name, interface_path=interface_path, 22 | message=service.event_message, include_directives=include_directives, 23 | type_supports=type_supports) 24 | }@ 25 | 26 | @{ 27 | from rosidl_generator_c import idl_structure_type_to_c_typename 28 | from rosidl_generator_type_description import GET_DESCRIPTION_FUNC 29 | from rosidl_generator_type_description import GET_HASH_FUNC 30 | from rosidl_generator_type_description import GET_SOURCES_FUNC 31 | from rosidl_parser.definition import SERVICE_EVENT_MESSAGE_SUFFIX 32 | from rosidl_parser.definition import SERVICE_REQUEST_MESSAGE_SUFFIX 33 | from rosidl_parser.definition import SERVICE_RESPONSE_MESSAGE_SUFFIX 34 | from rosidl_pycommon import convert_camel_case_to_lower_case_underscore 35 | include_parts = [package_name] + list(interface_path.parents[0].parts) + [ 36 | 'detail', convert_camel_case_to_lower_case_underscore(interface_path.stem)] 37 | include_base = '/'.join(include_parts) 38 | 39 | header_files = [ 40 | 'cstddef', 41 | 'rosidl_runtime_c/service_type_support_struct.h', 42 | include_base + '__type_support.h', 43 | ] 44 | if len(type_supports) != 1: 45 | header_files += [ 46 | 'rosidl_typesupport_c/identifier.h', 47 | 'rosidl_typesupport_c/service_type_support_dispatch.h', 48 | 'rosidl_typesupport_c/type_support_map.h', 49 | ] 50 | header_files.append('rosidl_typesupport_interface/macros.h') 51 | header_files.append('service_msgs/msg/service_event_info.h') 52 | header_files.append('builtin_interfaces/msg/time.h') 53 | }@ 54 | @[for header_file in header_files]@ 55 | @[ if header_file in include_directives]@ 56 | // already included above 57 | // @ 58 | @[ else]@ 59 | @{include_directives.add(header_file)}@ 60 | @[ end if]@ 61 | #include "@(header_file)" 62 | @[end for]@ 63 | @ 64 | @[if len(type_supports) != 1]@ 65 | @[ for ns in service.namespaced_type.namespaces]@ 66 | 67 | namespace @(ns) 68 | { 69 | @[ end for]@ 70 | 71 | namespace rosidl_typesupport_c 72 | { 73 | typedef struct _@(service.namespaced_type.name)_type_support_ids_t 74 | { 75 | const char * typesupport_identifier[@(len(type_supports))]; 76 | } _@(service.namespaced_type.name)_type_support_ids_t; 77 | 78 | static const _@(service.namespaced_type.name)_type_support_ids_t _@(service.namespaced_type.name)_service_typesupport_ids = { 79 | { 80 | @# TODO(dirk-thomas) use identifier symbol again 81 | @[for type_support in sorted(type_supports)]@ 82 | "@(type_support)", // ::@(type_support)::typesupport_identifier, 83 | @[end for]@ 84 | } 85 | }; 86 | 87 | typedef struct _@(service.namespaced_type.name)_type_support_symbol_names_t 88 | { 89 | const char * symbol_name[@(len(type_supports))]; 90 | } _@(service.namespaced_type.name)_type_support_symbol_names_t; 91 | 92 | #define STRINGIFY_(s) #s 93 | #define STRINGIFY(s) STRINGIFY_(s) 94 | 95 | static const _@(service.namespaced_type.name)_type_support_symbol_names_t _@(service.namespaced_type.name)_service_typesupport_symbol_names = { 96 | { 97 | @[for type_support in sorted(type_supports)]@ 98 | STRINGIFY(ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME(@(type_support), @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(service.namespaced_type.name))), 99 | @[end for]@ 100 | } 101 | }; 102 | 103 | typedef struct _@(service.namespaced_type.name)_type_support_data_t 104 | { 105 | void * data[@(len(type_supports))]; 106 | } _@(service.namespaced_type.name)_type_support_data_t; 107 | 108 | static _@(service.namespaced_type.name)_type_support_data_t _@(service.namespaced_type.name)_service_typesupport_data = { 109 | { 110 | @[for type_support in sorted(type_supports)]@ 111 | 0, // will store the shared library later 112 | @[end for]@ 113 | } 114 | }; 115 | 116 | static const type_support_map_t _@(service.namespaced_type.name)_service_typesupport_map = { 117 | @(len(type_supports)), 118 | "@(package_name)", 119 | &_@(service.namespaced_type.name)_service_typesupport_ids.typesupport_identifier[0], 120 | &_@(service.namespaced_type.name)_service_typesupport_symbol_names.symbol_name[0], 121 | &_@(service.namespaced_type.name)_service_typesupport_data.data[0], 122 | }; 123 | 124 | static const rosidl_service_type_support_t @(service.namespaced_type.name)_service_type_support_handle = { 125 | rosidl_typesupport_c__typesupport_identifier, 126 | reinterpret_cast(&_@(service.namespaced_type.name)_service_typesupport_map), 127 | rosidl_typesupport_c__get_service_typesupport_handle_function, 128 | &@(service.namespaced_type.name)@(SERVICE_REQUEST_MESSAGE_SUFFIX)_message_type_support_handle, 129 | &@(service.namespaced_type.name)@(SERVICE_RESPONSE_MESSAGE_SUFFIX)_message_type_support_handle, 130 | &@(service.namespaced_type.name)@(SERVICE_EVENT_MESSAGE_SUFFIX)_message_type_support_handle, 131 | ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_CREATE_EVENT_MESSAGE_SYMBOL_NAME( 132 | rosidl_typesupport_c, 133 | @(',\n '.join(service.namespaced_type.namespaced_name())) 134 | ), 135 | ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_DESTROY_EVENT_MESSAGE_SYMBOL_NAME( 136 | rosidl_typesupport_c, 137 | @(',\n '.join(service.namespaced_type.namespaced_name())) 138 | ), 139 | &@(idl_structure_type_to_c_typename(service.namespaced_type))__@(GET_HASH_FUNC), 140 | &@(idl_structure_type_to_c_typename(service.namespaced_type))__@(GET_DESCRIPTION_FUNC), 141 | &@(idl_structure_type_to_c_typename(service.namespaced_type))__@(GET_SOURCES_FUNC), 142 | }; 143 | 144 | } // namespace rosidl_typesupport_c 145 | @[ for ns in reversed(service.namespaced_type.namespaces)]@ 146 | 147 | } // namespace @(ns) 148 | @[ end for]@ 149 | 150 | @[else]@ 151 | @{ 152 | header_file = include_base + '__' + list(type_supports)[0] + '.h' 153 | }@ 154 | @[ if header_file in include_directives]@ 155 | // already included above 156 | // @ 157 | @[ else]@ 158 | @{include_directives.add(header_file)}@ 159 | @[ end if]@ 160 | #include "@(header_file)" 161 | 162 | @[end if]@ 163 | #ifdef __cplusplus 164 | extern "C" 165 | { 166 | #endif 167 | 168 | const rosidl_service_type_support_t * 169 | ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME(rosidl_typesupport_c, @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(service.namespaced_type.name))() { 170 | @[if len(type_supports) != 1]@ 171 | return &::@('::'.join([package_name] + list(interface_path.parents[0].parts)))::rosidl_typesupport_c::@(service.namespaced_type.name)_service_type_support_handle; 172 | @[else]@ 173 | return ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME(@(list(type_supports)[0]), @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(service.namespaced_type.name))(); 174 | @[end if]@ 175 | } 176 | 177 | #ifdef __cplusplus 178 | } 179 | #endif 180 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/resource/srv__type_support.cpp.em: -------------------------------------------------------------------------------- 1 | @# Included from rosidl_typesupport_cpp/resource/idl__type_support.cpp.em 2 | @{ 3 | TEMPLATE( 4 | 'msg__type_support.cpp.em', 5 | package_name=package_name, interface_path=interface_path, 6 | message=service.request_message, include_directives=include_directives, 7 | type_supports=type_supports) 8 | }@ 9 | 10 | @{ 11 | TEMPLATE( 12 | 'msg__type_support.cpp.em', 13 | package_name=package_name, interface_path=interface_path, 14 | message=service.response_message, include_directives=include_directives, 15 | type_supports=type_supports) 16 | }@ 17 | 18 | @{ 19 | TEMPLATE( 20 | 'msg__type_support.cpp.em', 21 | package_name=package_name, interface_path=interface_path, 22 | message=service.event_message, include_directives=include_directives, 23 | type_supports=type_supports) 24 | }@ 25 | 26 | @{ 27 | from rosidl_generator_c import idl_structure_type_to_c_typename 28 | from rosidl_generator_type_description import GET_DESCRIPTION_FUNC 29 | from rosidl_generator_type_description import GET_HASH_FUNC 30 | from rosidl_generator_type_description import GET_SOURCES_FUNC 31 | from rosidl_parser.definition import SERVICE_EVENT_MESSAGE_SUFFIX 32 | from rosidl_parser.definition import SERVICE_REQUEST_MESSAGE_SUFFIX 33 | from rosidl_parser.definition import SERVICE_RESPONSE_MESSAGE_SUFFIX 34 | from rosidl_pycommon import convert_camel_case_to_lower_case_underscore 35 | include_parts = [package_name] + list(interface_path.parents[0].parts) + [ 36 | 'detail', convert_camel_case_to_lower_case_underscore(interface_path.stem)] 37 | include_base = '/'.join(include_parts) 38 | 39 | header_files = [ 40 | 'cstddef', 41 | 'rosidl_runtime_c/service_type_support_struct.h', 42 | 'rosidl_typesupport_cpp/service_type_support.hpp', 43 | include_base + '__struct.hpp', 44 | ] 45 | if len(type_supports) != 1: 46 | header_files.append('rosidl_typesupport_cpp/identifier.hpp') 47 | if len(type_supports) != 1: 48 | header_files += [ 49 | 'rosidl_typesupport_c/type_support_map.h', 50 | 'rosidl_typesupport_cpp/service_type_support_dispatch.hpp', 51 | ] 52 | header_files.append('rosidl_typesupport_cpp/visibility_control.h') 53 | if len(type_supports) != 1: 54 | header_files.append('rosidl_typesupport_interface/macros.h') 55 | }@ 56 | @[for header_file in header_files]@ 57 | @[ if header_file in include_directives]@ 58 | // already included above 59 | // @ 60 | @[ else]@ 61 | @{include_directives.add(header_file)}@ 62 | @[ end if]@ 63 | #include "@(header_file)" 64 | @[end for]@ 65 | @ 66 | @[if len(type_supports) != 1]@ 67 | @[ for ns in service.namespaced_type.namespaces]@ 68 | 69 | namespace @(ns) 70 | { 71 | @[ end for]@ 72 | 73 | namespace rosidl_typesupport_cpp 74 | { 75 | 76 | typedef struct _@(service.namespaced_type.name)_type_support_ids_t 77 | { 78 | const char * typesupport_identifier[@(len(type_supports))]; 79 | } _@(service.namespaced_type.name)_type_support_ids_t; 80 | 81 | static const _@(service.namespaced_type.name)_type_support_ids_t _@(service.namespaced_type.name)_service_typesupport_ids = { 82 | { 83 | @# TODO(dirk-thomas) use identifier symbol again 84 | @[for type_support in sorted(type_supports)]@ 85 | "@(type_support)", // ::@(type_support)::typesupport_identifier, 86 | @[end for]@ 87 | } 88 | }; 89 | 90 | typedef struct _@(service.namespaced_type.name)_type_support_symbol_names_t 91 | { 92 | const char * symbol_name[@(len(type_supports))]; 93 | } _@(service.namespaced_type.name)_type_support_symbol_names_t; 94 | #define STRINGIFY_(s) #s 95 | #define STRINGIFY(s) STRINGIFY_(s) 96 | 97 | static const _@(service.namespaced_type.name)_type_support_symbol_names_t _@(service.namespaced_type.name)_service_typesupport_symbol_names = { 98 | { 99 | @[for type_support in sorted(type_supports)]@ 100 | STRINGIFY(ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME(@(type_support), @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(service.namespaced_type.name))), 101 | @[end for]@ 102 | } 103 | }; 104 | 105 | typedef struct _@(service.namespaced_type.name)_type_support_data_t 106 | { 107 | void * data[@(len(type_supports))]; 108 | } _@(service.namespaced_type.name)_type_support_data_t; 109 | 110 | static _@(service.namespaced_type.name)_type_support_data_t _@(service.namespaced_type.name)_service_typesupport_data = { 111 | { 112 | @[for type_support in sorted(type_supports)]@ 113 | 0, // will store the shared library later 114 | @[end for]@ 115 | } 116 | }; 117 | 118 | static const type_support_map_t _@(service.namespaced_type.name)_service_typesupport_map = { 119 | @(len(type_supports)), 120 | "@(package_name)", 121 | &_@(service.namespaced_type.name)_service_typesupport_ids.typesupport_identifier[0], 122 | &_@(service.namespaced_type.name)_service_typesupport_symbol_names.symbol_name[0], 123 | &_@(service.namespaced_type.name)_service_typesupport_data.data[0], 124 | }; 125 | 126 | static const rosidl_service_type_support_t @(service.namespaced_type.name)_service_type_support_handle = { 127 | ::rosidl_typesupport_cpp::typesupport_identifier, 128 | reinterpret_cast(&_@(service.namespaced_type.name)_service_typesupport_map), 129 | ::rosidl_typesupport_cpp::get_service_typesupport_handle_function, 130 | ::rosidl_typesupport_cpp::get_message_type_support_handle<@('::'.join([package_name, *interface_path.parents[0].parts, service.namespaced_type.name]))@(SERVICE_REQUEST_MESSAGE_SUFFIX)>(), 131 | ::rosidl_typesupport_cpp::get_message_type_support_handle<@('::'.join([package_name, *interface_path.parents[0].parts, service.namespaced_type.name]))@(SERVICE_RESPONSE_MESSAGE_SUFFIX)>(), 132 | ::rosidl_typesupport_cpp::get_message_type_support_handle<@('::'.join([package_name, *interface_path.parents[0].parts, service.namespaced_type.name]))@(SERVICE_EVENT_MESSAGE_SUFFIX)>(), 133 | &::rosidl_typesupport_cpp::service_create_event_message<@('::'.join([package_name, *interface_path.parents[0].parts, service.namespaced_type.name]))>, 134 | &::rosidl_typesupport_cpp::service_destroy_event_message<@('::'.join([package_name, *interface_path.parents[0].parts, service.namespaced_type.name]))>, 135 | &@(idl_structure_type_to_c_typename(service.namespaced_type))__@(GET_HASH_FUNC), 136 | &@(idl_structure_type_to_c_typename(service.namespaced_type))__@(GET_DESCRIPTION_FUNC), 137 | &@(idl_structure_type_to_c_typename(service.namespaced_type))__@(GET_SOURCES_FUNC), 138 | }; 139 | 140 | } // namespace rosidl_typesupport_cpp 141 | @[ for ns in reversed(service.namespaced_type.namespaces)]@ 142 | 143 | } // namespace @(ns) 144 | @[ end for]@ 145 | 146 | @[else]@ 147 | @{ 148 | include_parts = [package_name] + list(interface_path.parents[0].parts) + [ 149 | 'detail', convert_camel_case_to_lower_case_underscore(interface_path.stem)] 150 | include_base = '/'.join(include_parts) 151 | header_file = include_base + '__' + list(type_supports)[0] + '.hpp' 152 | }@ 153 | @[ if header_file in include_directives]@ 154 | // already included above 155 | // @ 156 | @[ else]@ 157 | @{include_directives.add(header_file)}@ 158 | @[ end if]@ 159 | #include "@(header_file)" 160 | 161 | @[end if]@ 162 | namespace rosidl_typesupport_cpp 163 | { 164 | 165 | template<> 166 | ROSIDL_TYPESUPPORT_CPP_PUBLIC 167 | const rosidl_service_type_support_t * 168 | get_service_type_support_handle<@('::'.join([package_name] + list(interface_path.parents[0].parts)))::@(service.namespaced_type.name)>() 169 | { 170 | @[if len(type_supports) != 1]@ 171 | return &::@('::'.join([package_name] + list(interface_path.parents[0].parts)))::rosidl_typesupport_cpp::@(service.namespaced_type.name)_service_type_support_handle; 172 | @[else]@ 173 | return ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME(@(list(type_supports)[0]), @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(service.namespaced_type.name))(); 174 | @[end if]@ 175 | } 176 | 177 | } // namespace rosidl_typesupport_cpp 178 | 179 | #ifdef __cplusplus 180 | extern "C" 181 | { 182 | #endif 183 | 184 | ROSIDL_TYPESUPPORT_CPP_PUBLIC 185 | const rosidl_service_type_support_t * 186 | ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME(rosidl_typesupport_cpp, @(', '.join([package_name] + list(interface_path.parents[0].parts) + [service.namespaced_type.name])))() { 187 | return ::rosidl_typesupport_cpp::get_service_type_support_handle<@('::'.join([package_name] + list(interface_path.parents[0].parts) + [service.namespaced_type.name]))>(); 188 | } 189 | 190 | #ifdef __cplusplus 191 | } 192 | #endif 193 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/cmake/rosidl_typesupport_c_generate_interfaces.cmake: -------------------------------------------------------------------------------- 1 | # Copyright 2016-2018 Open Source Robotics Foundation, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | if(NOT TARGET ${rosidl_generate_interfaces_TARGET}__rosidl_generator_c) 16 | message(FATAL_ERROR 17 | "The 'rosidl_generator_c' extension must be executed before the " 18 | "'rosidl_typesupport_c' extension.") 19 | endif() 20 | 21 | find_package(rosidl_runtime_c REQUIRED) 22 | find_package(rosidl_typesupport_interface REQUIRED) 23 | 24 | set(_output_path 25 | "${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_c/${PROJECT_NAME}") 26 | set(_generated_sources "") 27 | foreach(_abs_idl_file ${rosidl_generate_interfaces_ABS_IDL_FILES}) 28 | get_filename_component(_parent_folder "${_abs_idl_file}" DIRECTORY) 29 | get_filename_component(_parent_folder "${_parent_folder}" NAME) 30 | get_filename_component(_idl_name "${_abs_idl_file}" NAME_WE) 31 | string_camel_case_to_lower_case_underscore("${_idl_name}" _header_name) 32 | list(APPEND _generated_sources 33 | "${_output_path}/${_parent_folder}/${_header_name}__type_support.cpp" 34 | ) 35 | endforeach() 36 | 37 | set(_dependency_files "") 38 | set(_dependencies "") 39 | foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES}) 40 | foreach(_idl_file ${${_pkg_name}_IDL_FILES}) 41 | set(_abs_idl_file "${${_pkg_name}_DIR}/../${_idl_file}") 42 | normalize_path(_abs_idl_file "${_abs_idl_file}") 43 | list(APPEND _dependency_files "${_abs_idl_file}") 44 | list(APPEND _dependencies "${_pkg_name}:${_abs_idl_file}") 45 | endforeach() 46 | endforeach() 47 | 48 | set(target_dependencies 49 | "${rosidl_typesupport_c_BIN}" 50 | ${rosidl_typesupport_c_GENERATOR_FILES} 51 | "${rosidl_typesupport_c_TEMPLATE_DIR}/action__type_support.c.em" 52 | "${rosidl_typesupport_c_TEMPLATE_DIR}/idl__type_support.cpp.em" 53 | "${rosidl_typesupport_c_TEMPLATE_DIR}/msg__type_support.cpp.em" 54 | "${rosidl_typesupport_c_TEMPLATE_DIR}/srv__type_support.cpp.em" 55 | ${rosidl_generate_interfaces_ABS_IDL_FILES} 56 | ${_dependency_files}) 57 | foreach(dep ${target_dependencies}) 58 | if(NOT EXISTS "${dep}") 59 | message(FATAL_ERROR "Target dependency '${dep}' does not exist") 60 | endif() 61 | endforeach() 62 | 63 | set(generator_arguments_file "${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_c__arguments.json") 64 | rosidl_write_generator_arguments( 65 | "${generator_arguments_file}" 66 | PACKAGE_NAME "${PROJECT_NAME}" 67 | IDL_TUPLES "${rosidl_generate_interfaces_IDL_TUPLES}" 68 | ROS_INTERFACE_DEPENDENCIES "${_dependencies}" 69 | OUTPUT_DIR "${_output_path}" 70 | TEMPLATE_DIR "${rosidl_typesupport_c_TEMPLATE_DIR}" 71 | TARGET_DEPENDENCIES ${target_dependencies} 72 | ) 73 | 74 | # By default, without the settings below, find_package(Python3) will attempt 75 | # to find the newest python version it can, and additionally will find the 76 | # most specific version. For instance, on a system that has 77 | # /usr/bin/python3.10, /usr/bin/python3.11, and /usr/bin/python3, it will find 78 | # /usr/bin/python3.11, even if /usr/bin/python3 points to /usr/bin/python3.10. 79 | # The behavior we want is to prefer the "system" installed version unless the 80 | # user specifically tells us othewise through the Python3_EXECUTABLE hint. 81 | # Setting CMP0094 to NEW means that the search will stop after the first 82 | # python version is found. Setting Python3_FIND_UNVERSIONED_NAMES means that 83 | # the search will prefer /usr/bin/python3 over /usr/bin/python3.11. And that 84 | # latter functionality is only available in CMake 3.20 or later, so we need 85 | # at least that version. 86 | cmake_minimum_required(VERSION 3.20) 87 | cmake_policy(SET CMP0094 NEW) 88 | set(Python3_FIND_UNVERSIONED_NAMES FIRST) 89 | 90 | find_package(Python3 REQUIRED COMPONENTS Interpreter) 91 | 92 | get_used_typesupports(typesupports "rosidl_typesupport_c") 93 | add_custom_command( 94 | OUTPUT ${_generated_sources} 95 | COMMAND Python3::Interpreter 96 | ARGS ${rosidl_typesupport_c_BIN} 97 | --generator-arguments-file "${generator_arguments_file}" 98 | --typesupports ${typesupports} 99 | DEPENDS ${target_dependencies} 100 | COMMENT "Generating C type support dispatch for ROS interfaces" 101 | VERBATIM 102 | ) 103 | 104 | set(_target_suffix "__rosidl_typesupport_c") 105 | 106 | add_library(${rosidl_generate_interfaces_TARGET}${_target_suffix} ${rosidl_typesupport_c_LIBRARY_TYPE} ${_generated_sources}) 107 | if(rosidl_generate_interfaces_LIBRARY_NAME) 108 | set_target_properties(${rosidl_generate_interfaces_TARGET}${_target_suffix} 109 | PROPERTIES OUTPUT_NAME "${rosidl_generate_interfaces_LIBRARY_NAME}${_target_suffix}") 110 | endif() 111 | 112 | # The visibility header macros for symbols defined by this package are created by rosidl_generator_c 113 | set_property(TARGET ${rosidl_generate_interfaces_TARGET}${_target_suffix} 114 | PROPERTY DEFINE_SYMBOL "ROSIDL_GENERATOR_C_BUILDING_DLL_${PROJECT_NAME}") 115 | 116 | set_target_properties(${rosidl_generate_interfaces_TARGET}${_target_suffix} 117 | PROPERTIES CXX_STANDARD 17) 118 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 119 | set_target_properties(${rosidl_generate_interfaces_TARGET}${_target_suffix} 120 | PROPERTIES COMPILE_OPTIONS -Wall -Wextra -Wpedantic) 121 | endif() 122 | 123 | # if only a single typesupport is used this package will directly reference it 124 | # therefore it needs to link against the selected typesupport 125 | if(NOT typesupports MATCHES ";") 126 | target_link_libraries(${rosidl_generate_interfaces_TARGET}${_target_suffix} PRIVATE 127 | ${rosidl_generate_interfaces_TARGET}__${typesupports}) 128 | else() 129 | if("${rosidl_typesupport_c_LIBRARY_TYPE}" STREQUAL "STATIC") 130 | message(FATAL_ERROR "Multiple typesupports [${typesupports}] but static " 131 | "linking was requested") 132 | endif() 133 | endif() 134 | 135 | # Depend on the target created by rosidl_generator_c 136 | target_link_libraries(${rosidl_generate_interfaces_TARGET}${_target_suffix} PUBLIC 137 | ${rosidl_generate_interfaces_TARGET}__rosidl_generator_c) 138 | 139 | target_link_libraries(${rosidl_generate_interfaces_TARGET}${_target_suffix} PRIVATE 140 | rosidl_runtime_c::rosidl_runtime_c 141 | rosidl_typesupport_c::rosidl_typesupport_c 142 | rosidl_typesupport_interface::rosidl_typesupport_interface) 143 | 144 | # Depend on dependencies 145 | foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES}) 146 | target_link_libraries(${rosidl_generate_interfaces_TARGET}${_target_suffix} PUBLIC 147 | ${${_pkg_name}_TARGETS${_target_suffix}}) 148 | endforeach() 149 | 150 | # Make top level generation target depend on this library 151 | add_dependencies( 152 | ${rosidl_generate_interfaces_TARGET} 153 | ${rosidl_generate_interfaces_TARGET}${_target_suffix} 154 | ) 155 | 156 | if(NOT rosidl_generate_interfaces_SKIP_INSTALL) 157 | install( 158 | TARGETS ${rosidl_generate_interfaces_TARGET}${_target_suffix} 159 | EXPORT ${rosidl_generate_interfaces_TARGET}${_target_suffix} 160 | ARCHIVE DESTINATION lib 161 | LIBRARY DESTINATION lib 162 | RUNTIME DESTINATION bin 163 | ) 164 | 165 | # Export old-style CMake variables 166 | ament_export_libraries(${rosidl_generate_interfaces_TARGET}${_target_suffix}) 167 | 168 | # Export modern CMake targets 169 | ament_export_targets(${rosidl_generate_interfaces_TARGET}${_target_suffix}) 170 | rosidl_export_typesupport_targets(${_target_suffix} 171 | ${rosidl_generate_interfaces_TARGET}${_target_suffix}) 172 | 173 | ament_export_dependencies( 174 | "rosidl_runtime_c" 175 | "rosidl_typesupport_c" 176 | "rosidl_typesupport_interface") 177 | endif() 178 | 179 | if(BUILD_TESTING AND rosidl_generate_interfaces_ADD_LINTER_TESTS) 180 | find_package(ament_cmake_cppcheck REQUIRED) 181 | ament_cppcheck( 182 | TESTNAME "cppcheck_rosidl_typesupport_c" 183 | "${_output_path}") 184 | 185 | find_package(ament_cmake_cpplint REQUIRED) 186 | get_filename_component(_cpplint_root "${_output_path}" DIRECTORY) 187 | ament_cpplint( 188 | TESTNAME "cpplint_rosidl_typesupport_c" 189 | # the generated code might contain longer lines for templated types 190 | MAX_LINE_LENGTH 999 191 | ROOT "${_cpplint_root}" 192 | "${_output_path}") 193 | 194 | find_package(ament_cmake_uncrustify REQUIRED) 195 | ament_uncrustify( 196 | TESTNAME "uncrustify_rosidl_typesupport_c" 197 | # the generated code might contain longer lines for templated types 198 | # a value of zero tells uncrustify to ignore line lengths 199 | MAX_LINE_LENGTH 0 200 | "${_output_path}") 201 | endif() 202 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/cmake/rosidl_typesupport_cpp_generate_interfaces.cmake: -------------------------------------------------------------------------------- 1 | # Copyright 2016-2018 Open Source Robotics Foundation, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | if(NOT TARGET ${rosidl_generate_interfaces_TARGET}__rosidl_generator_cpp) 16 | message(FATAL_ERROR 17 | "The 'rosidl_generator_cpp' extension must be executed before the " 18 | "'rosidl_typesupport_cpp' extension.") 19 | endif() 20 | 21 | set(_output_path 22 | "${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_cpp/${PROJECT_NAME}") 23 | set(_generated_sources "") 24 | foreach(_abs_idl_file ${rosidl_generate_interfaces_ABS_IDL_FILES}) 25 | get_filename_component(_parent_folder "${_abs_idl_file}" DIRECTORY) 26 | get_filename_component(_parent_folder "${_parent_folder}" NAME) 27 | get_filename_component(_idl_name "${_abs_idl_file}" NAME_WE) 28 | string_camel_case_to_lower_case_underscore("${_idl_name}" _header_name) 29 | list(APPEND _generated_sources 30 | "${_output_path}/${_parent_folder}/${_header_name}__type_support.cpp" 31 | ) 32 | endforeach() 33 | 34 | set(_dependency_files "") 35 | set(_dependencies "") 36 | foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES}) 37 | foreach(_idl_file ${${_pkg_name}_IDL_FILES}) 38 | set(_abs_idl_file "${${_pkg_name}_DIR}/../${_idl_file}") 39 | normalize_path(_abs_idl_file "${_abs_idl_file}") 40 | list(APPEND _dependency_files "${_abs_idl_file}") 41 | list(APPEND _dependencies "${_pkg_name}:${_abs_idl_file}") 42 | endforeach() 43 | endforeach() 44 | 45 | set(target_dependencies 46 | "${rosidl_typesupport_cpp_BIN}" 47 | ${rosidl_typesupport_cpp_GENERATOR_FILES} 48 | "${rosidl_typesupport_cpp_TEMPLATE_DIR}/action__type_support.cpp.em" 49 | "${rosidl_typesupport_cpp_TEMPLATE_DIR}/idl__type_support.cpp.em" 50 | "${rosidl_typesupport_cpp_TEMPLATE_DIR}/msg__type_support.cpp.em" 51 | "${rosidl_typesupport_cpp_TEMPLATE_DIR}/srv__type_support.cpp.em" 52 | ${rosidl_generate_interfaces_ABS_IDL_FILES} 53 | ${_dependency_files}) 54 | foreach(dep ${target_dependencies}) 55 | if(NOT EXISTS "${dep}") 56 | message(FATAL_ERROR "Target dependency '${dep}' does not exist") 57 | endif() 58 | endforeach() 59 | 60 | set(generator_arguments_file "${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_cpp__arguments.json") 61 | rosidl_write_generator_arguments( 62 | "${generator_arguments_file}" 63 | PACKAGE_NAME "${PROJECT_NAME}" 64 | IDL_TUPLES "${rosidl_generate_interfaces_IDL_TUPLES}" 65 | ROS_INTERFACE_DEPENDENCIES "${_dependencies}" 66 | OUTPUT_DIR "${_output_path}" 67 | TEMPLATE_DIR "${rosidl_typesupport_cpp_TEMPLATE_DIR}" 68 | TARGET_DEPENDENCIES ${target_dependencies} 69 | ) 70 | 71 | # By default, without the settings below, find_package(Python3) will attempt 72 | # to find the newest python version it can, and additionally will find the 73 | # most specific version. For instance, on a system that has 74 | # /usr/bin/python3.10, /usr/bin/python3.11, and /usr/bin/python3, it will find 75 | # /usr/bin/python3.11, even if /usr/bin/python3 points to /usr/bin/python3.10. 76 | # The behavior we want is to prefer the "system" installed version unless the 77 | # user specifically tells us othewise through the Python3_EXECUTABLE hint. 78 | # Setting CMP0094 to NEW means that the search will stop after the first 79 | # python version is found. Setting Python3_FIND_UNVERSIONED_NAMES means that 80 | # the search will prefer /usr/bin/python3 over /usr/bin/python3.11. And that 81 | # latter functionality is only available in CMake 3.20 or later, so we need 82 | # at least that version. 83 | cmake_minimum_required(VERSION 3.20) 84 | cmake_policy(SET CMP0094 NEW) 85 | set(Python3_FIND_UNVERSIONED_NAMES FIRST) 86 | 87 | find_package(Python3 REQUIRED COMPONENTS Interpreter) 88 | 89 | get_used_typesupports(typesupports "rosidl_typesupport_cpp") 90 | add_custom_command( 91 | OUTPUT ${_generated_sources} 92 | COMMAND Python3::Interpreter 93 | ARGS ${rosidl_typesupport_cpp_BIN} 94 | --generator-arguments-file "${generator_arguments_file}" 95 | --typesupports ${typesupports} 96 | DEPENDS ${target_dependencies} 97 | COMMENT "Generating C++ type support dispatch for ROS interfaces" 98 | VERBATIM 99 | ) 100 | 101 | set(_target_suffix "__rosidl_typesupport_cpp") 102 | 103 | add_library(${rosidl_generate_interfaces_TARGET}${_target_suffix} ${rosidl_typesupport_cpp_LIBRARY_TYPE} ${_generated_sources}) 104 | if(rosidl_generate_interfaces_LIBRARY_NAME) 105 | set_target_properties(${rosidl_generate_interfaces_TARGET}${_target_suffix} 106 | PROPERTIES OUTPUT_NAME "${rosidl_generate_interfaces_LIBRARY_NAME}${_target_suffix}") 107 | endif() 108 | set_target_properties(${rosidl_generate_interfaces_TARGET}${_target_suffix} 109 | PROPERTIES 110 | DEFINE_SYMBOL "ROSIDL_TYPESUPPORT_CPP_BUILDING_DLL" 111 | CXX_STANDARD 17) 112 | 113 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 114 | target_compile_options(${rosidl_generate_interfaces_TARGET}${_target_suffix} 115 | PRIVATE -Wall -Wextra -Wpedantic) 116 | endif() 117 | 118 | # if only a single typesupport is used this package will directly reference it 119 | # therefore it needs to link against the selected typesupport 120 | if(NOT typesupports MATCHES ";") 121 | target_include_directories(${rosidl_generate_interfaces_TARGET}${_target_suffix} 122 | PUBLIC 123 | "$") 124 | target_link_libraries(${rosidl_generate_interfaces_TARGET}${_target_suffix} PRIVATE 125 | ${rosidl_generate_interfaces_TARGET}__${typesupports}) 126 | else() 127 | if("${rosidl_typesupport_cpp_LIBRARY_TYPE}" STREQUAL "STATIC") 128 | message(FATAL_ERROR "Multiple typesupports [${typesupports}] but static " 129 | "linking was requested") 130 | endif() 131 | endif() 132 | 133 | # Depend on the target created by rosidl_generator_cpp 134 | target_link_libraries(${rosidl_generate_interfaces_TARGET}${_target_suffix} PUBLIC 135 | ${rosidl_generate_interfaces_TARGET}__rosidl_generator_c 136 | ${rosidl_generate_interfaces_TARGET}__rosidl_generator_cpp) 137 | 138 | target_link_libraries(${rosidl_generate_interfaces_TARGET}${_target_suffix} PRIVATE 139 | rosidl_runtime_c::rosidl_runtime_c 140 | rosidl_runtime_cpp::rosidl_runtime_cpp 141 | rosidl_typesupport_cpp::rosidl_typesupport_cpp 142 | rosidl_typesupport_c::rosidl_typesupport_c 143 | rosidl_typesupport_interface::rosidl_typesupport_interface) 144 | 145 | foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES}) 146 | target_link_libraries(${rosidl_generate_interfaces_TARGET}${_target_suffix} PUBLIC 147 | ${${_pkg_name}_TARGETS${_target_suffix}}) 148 | endforeach() 149 | 150 | # Make top level generation target depend on this library 151 | add_dependencies( 152 | ${rosidl_generate_interfaces_TARGET} 153 | ${rosidl_generate_interfaces_TARGET}${_target_suffix} 154 | ) 155 | 156 | if(NOT rosidl_generate_interfaces_SKIP_INSTALL) 157 | install( 158 | TARGETS ${rosidl_generate_interfaces_TARGET}${_target_suffix} 159 | EXPORT ${rosidl_generate_interfaces_TARGET}${_target_suffix} 160 | ARCHIVE DESTINATION lib 161 | LIBRARY DESTINATION lib 162 | RUNTIME DESTINATION bin 163 | ) 164 | 165 | # Export old-style CMake variables 166 | ament_export_libraries(${rosidl_generate_interfaces_TARGET}${_target_suffix}) 167 | 168 | # Export modern CMake targets 169 | ament_export_targets(${rosidl_generate_interfaces_TARGET}${_target_suffix}) 170 | rosidl_export_typesupport_targets(${_target_suffix} 171 | ${rosidl_generate_interfaces_TARGET}${_target_suffix}) 172 | 173 | ament_export_dependencies( 174 | "rosidl_runtime_c" 175 | "rosidl_runtime_cpp" 176 | "rosidl_typesupport_c" 177 | "rosidl_typesupport_cpp" 178 | "rosidl_typesupport_interface") 179 | endif() 180 | 181 | if(BUILD_TESTING AND rosidl_generate_interfaces_ADD_LINTER_TESTS) 182 | find_package(ament_cmake_cppcheck REQUIRED) 183 | ament_cppcheck( 184 | TESTNAME "cppcheck_rosidl_typesupport_cpp" 185 | "${_output_path}") 186 | 187 | find_package(ament_cmake_cpplint REQUIRED) 188 | get_filename_component(_cpplint_root "${_output_path}" DIRECTORY) 189 | ament_cpplint( 190 | TESTNAME "cpplint_rosidl_typesupport_cpp" 191 | # the generated code might contain longer lines for templated types 192 | MAX_LINE_LENGTH 999 193 | ROOT "${_cpplint_root}" 194 | "${_output_path}") 195 | 196 | find_package(ament_cmake_uncrustify REQUIRED) 197 | ament_uncrustify( 198 | TESTNAME "uncrustify_rosidl_typesupport_cpp" 199 | # the generated code might contain longer lines for templated types 200 | # a value of zero tells uncrustify to ignore line length 201 | MAX_LINE_LENGTH 0 202 | "${_output_path}") 203 | endif() 204 | -------------------------------------------------------------------------------- /rosidl_typesupport_tests/test/rosidl_typesupport_cpp/test_service_typesupport.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include "gtest/gtest.h" 21 | 22 | #include "rcutils/allocator.h" 23 | 24 | #include "rosidl_typesupport_cpp/message_type_support.hpp" 25 | #include "rosidl_typesupport_cpp/service_type_support.hpp" 26 | 27 | #include "rosidl_typesupport_tests/action/fibonacci.hpp" 28 | #include "rosidl_typesupport_tests/srv/basic_types.hpp" 29 | 30 | #include "rmw/rmw.h" 31 | 32 | TEST(test_service_typesupport, event_message_create_and_destroy_invalid_arguments) 33 | { 34 | rcutils_allocator_t allocator = rcutils_get_default_allocator(); 35 | const rosidl_service_type_support_t * srv_ts = 36 | rosidl_typesupport_cpp::get_service_type_support_handle(); // NOLINT 37 | 38 | rosidl_service_introspection_info_t valid_info; 39 | 40 | // null info 41 | { 42 | EXPECT_THROW( 43 | srv_ts->event_message_create_handle_function(nullptr, &allocator, nullptr, nullptr), 44 | std::invalid_argument); 45 | } 46 | // null allocator 47 | { 48 | EXPECT_THROW( 49 | srv_ts->event_message_create_handle_function(&valid_info, nullptr, nullptr, nullptr), 50 | std::invalid_argument); 51 | } 52 | } 53 | 54 | TEST(test_service_typesupport, basic_types_event_message_create) 55 | { 56 | rcutils_allocator_t allocator = rcutils_get_default_allocator(); 57 | const rosidl_service_type_support_t * srv_ts = 58 | rosidl_typesupport_cpp::get_service_type_support_handle(); // NOLINT 59 | 60 | const rosidl_message_type_support_t * msg_ts = 61 | rosidl_typesupport_cpp::get_message_type_support_handle(); // NOLINT 62 | 63 | if (std::string(rmw_get_implementation_identifier()).find("rmw_cyclonedds") == 0) { 64 | EXPECT_STREQ( 65 | srv_ts->typesupport_identifier, 66 | "rosidl_typesupport_introspection_cpp"); 67 | EXPECT_STREQ( 68 | msg_ts->typesupport_identifier, 69 | "rosidl_typesupport_introspection_cpp"); 70 | } else { 71 | EXPECT_STREQ(srv_ts->typesupport_identifier, "rosidl_typesupport_cpp"); 72 | EXPECT_STREQ(msg_ts->typesupport_identifier, "rosidl_typesupport_cpp"); 73 | } 74 | 75 | // typesupports are static so this comparison *should* be valid? 76 | EXPECT_EQ(srv_ts->event_typesupport, msg_ts); 77 | 78 | rosidl_service_introspection_info_t expected_info; 79 | expected_info.sequence_number = 2; 80 | expected_info.event_type = 2; 81 | expected_info.stamp_nanosec = 123; 82 | expected_info.stamp_sec = 123; 83 | auto gid = std::array{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; 84 | std::copy(gid.begin(), gid.end(), expected_info.client_gid); 85 | 86 | auto expected_request = rosidl_typesupport_tests::srv::BasicTypes_Request(); 87 | expected_request.int16_value = -1; 88 | expected_request.uint16_value = 123; 89 | auto expected_response = rosidl_typesupport_tests::srv::BasicTypes_Response(); 90 | expected_response.bool_value = true; 91 | expected_response.string_value = "hello world"; 92 | 93 | // null request and response arguments 94 | { 95 | auto * event = static_cast( 96 | srv_ts->event_message_create_handle_function(&expected_info, &allocator, nullptr, nullptr)); 97 | ASSERT_NE(event, nullptr); 98 | EXPECT_EQ(event->info.sequence_number, expected_info.sequence_number); 99 | EXPECT_EQ(event->info.event_type, expected_info.event_type); 100 | EXPECT_EQ(event->info.stamp.nanosec, expected_info.stamp_nanosec); 101 | EXPECT_EQ(event->info.stamp.sec, expected_info.stamp_sec); 102 | for (int i = 0; i < 16; ++i) { 103 | EXPECT_EQ(event->info.client_gid[i], expected_info.client_gid[i]); 104 | } 105 | EXPECT_EQ(event->request.size(), 0U); 106 | EXPECT_EQ(event->response.size(), 0U); 107 | 108 | ASSERT_TRUE(srv_ts->event_message_destroy_handle_function(event, &allocator)); 109 | } 110 | 111 | // request argument set, null response argument 112 | { 113 | auto * event = static_cast( 114 | srv_ts->event_message_create_handle_function( 115 | &expected_info, 116 | &allocator, 117 | static_cast(&expected_request), 118 | nullptr)); 119 | 120 | ASSERT_NE(event, nullptr); 121 | EXPECT_EQ(event->info.sequence_number, expected_info.sequence_number); 122 | EXPECT_EQ(event->info.event_type, expected_info.event_type); 123 | EXPECT_EQ(event->info.stamp.nanosec, expected_info.stamp_nanosec); 124 | EXPECT_EQ(event->info.stamp.sec, expected_info.stamp_sec); 125 | for (int i = 0; i < 16; ++i) { 126 | EXPECT_EQ(event->info.client_gid[i], expected_info.client_gid[i]); 127 | } 128 | ASSERT_EQ(event->request.size(), 1U); 129 | EXPECT_EQ(event->response.size(), 0U); 130 | EXPECT_EQ(event->request[0].int16_value, expected_request.int16_value); 131 | EXPECT_EQ(event->request[0].uint16_value, expected_request.uint16_value); 132 | ASSERT_TRUE(srv_ts->event_message_destroy_handle_function(event, &allocator)); 133 | } 134 | 135 | // response argument set, null request argument 136 | { 137 | auto * event = static_cast( 138 | srv_ts->event_message_create_handle_function( 139 | &expected_info, 140 | &allocator, 141 | nullptr, 142 | static_cast(&expected_response))); 143 | 144 | ASSERT_NE(event, nullptr); 145 | EXPECT_EQ(event->info.sequence_number, expected_info.sequence_number); 146 | EXPECT_EQ(event->info.event_type, expected_info.event_type); 147 | EXPECT_EQ(event->info.stamp.nanosec, expected_info.stamp_nanosec); 148 | EXPECT_EQ(event->info.stamp.sec, expected_info.stamp_sec); 149 | for (int i = 0; i < 16; ++i) { 150 | EXPECT_EQ(event->info.client_gid[i], expected_info.client_gid[i]); 151 | } 152 | EXPECT_EQ(event->request.size(), 0U); 153 | ASSERT_EQ(event->response.size(), 1U); 154 | EXPECT_EQ(event->response[0].bool_value, expected_response.bool_value); 155 | EXPECT_EQ(event->response[0].string_value, expected_response.string_value); 156 | ASSERT_TRUE(srv_ts->event_message_destroy_handle_function(event, &allocator)); 157 | } 158 | 159 | // both request and response arguments set 160 | { 161 | auto * event = static_cast( 162 | srv_ts->event_message_create_handle_function( 163 | &expected_info, 164 | &allocator, 165 | static_cast(&expected_request), 166 | static_cast(&expected_response))); 167 | 168 | ASSERT_NE(event, nullptr); 169 | EXPECT_EQ(event->info.sequence_number, expected_info.sequence_number); 170 | EXPECT_EQ(event->info.event_type, expected_info.event_type); 171 | EXPECT_EQ(event->info.stamp.nanosec, expected_info.stamp_nanosec); 172 | EXPECT_EQ(event->info.stamp.sec, expected_info.stamp_sec); 173 | for (int i = 0; i < 16; ++i) { 174 | EXPECT_EQ(event->info.client_gid[i], expected_info.client_gid[i]); 175 | } 176 | ASSERT_EQ(event->request.size(), 1U); 177 | EXPECT_EQ(event->request[0].int16_value, expected_request.int16_value); 178 | EXPECT_EQ(event->request[0].uint16_value, expected_request.uint16_value); 179 | ASSERT_EQ(event->response.size(), 1U); 180 | EXPECT_EQ(event->response[0].bool_value, expected_response.bool_value); 181 | EXPECT_EQ(event->response[0].string_value, expected_response.string_value); 182 | ASSERT_TRUE(srv_ts->event_message_destroy_handle_function(event, &allocator)); 183 | } 184 | } 185 | 186 | TEST(test_service_typesupport, fibonacci_action_services_event) 187 | { 188 | const rosidl_message_type_support_t * send_goal_event_msg_ts = 189 | rosidl_typesupport_cpp::get_message_type_support_handle< 190 | rosidl_typesupport_tests::action::Fibonacci_SendGoal::Event>(); 191 | const rosidl_message_type_support_t * get_result_event_msg_ts = 192 | rosidl_typesupport_cpp::get_message_type_support_handle< 193 | rosidl_typesupport_tests::action::Fibonacci_GetResult::Event>(); 194 | ASSERT_NE(nullptr, send_goal_event_msg_ts); 195 | ASSERT_NE(nullptr, get_result_event_msg_ts); 196 | if (std::string(rmw_get_implementation_identifier()).find("rmw_cyclonedds") == 0) { 197 | EXPECT_STREQ( 198 | send_goal_event_msg_ts->typesupport_identifier, 199 | "rosidl_typesupport_introspection_cpp"); 200 | EXPECT_STREQ( 201 | get_result_event_msg_ts->typesupport_identifier, 202 | "rosidl_typesupport_introspection_cpp"); 203 | } else { 204 | EXPECT_STREQ(send_goal_event_msg_ts->typesupport_identifier, "rosidl_typesupport_cpp"); 205 | EXPECT_STREQ(get_result_event_msg_ts->typesupport_identifier, "rosidl_typesupport_cpp"); 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /rosidl_typesupport_c/QUALITY_DECLARATION.md: -------------------------------------------------------------------------------- 1 | This document is a declaration of software quality for the `rosidl_typesupport_c` package, based on the guidelines in [REP-2004](https://www.ros.org/reps/rep-2004.html). 2 | 3 | # rosidl_typesupport_c Quality Declaration 4 | 5 | The package `rosidl_typesupport_c` claims to be in the **Quality Level 1** category. 6 | 7 | Below are the rationales, notes, and caveats for this claim, organized by each requirement listed in the [Package Requirements for Quality Level 1 in REP-2004](https://www.ros.org/reps/rep-2004.html). 8 | 9 | ## Version Policy [1] 10 | 11 | ### Version Scheme [1.i] 12 | 13 | `rosidl_typesupport_c` uses `semver` according to the recommendation for ROS Core packages in the [ROS 2 Developer Guide](https://docs.ros.org/en/rolling/Contributing/Developer-Guide.html#versioning). 14 | 15 | ### Version Stability [1.ii] 16 | 17 | `rosidl_typesupport_c` is at a stable version, i.e. >= 1.0.0. The current version can be found in its [package.xml](./package.xml), and its change history can be found in its [CHANGELOG](./CHANGELOG.rst). 18 | 19 | ### Public API Declaration [1.iii] 20 | 21 | All symbols in the installed headers are considered part of the public API. 22 | 23 | All installed headers are in the `include` directory of the package, headers in any other folders are not installed and considered private. 24 | 25 | ### API Stability Within a Released ROS Distribution [1.iv]/[1.vi] 26 | 27 | `rosidl_typesupport_c` will not break public API within a released ROS distribution, i.e. no major releases once the ROS distribution is released. 28 | 29 | ### ABI Stability Within a Released ROS Distribution [1.v]/[1.vi] 30 | 31 | `rosidl_typesupport_c` contains C code and therefore must be concerned with ABI stability, and will maintain ABI stability within a ROS distribution. 32 | 33 | ## Change Control Process [2] 34 | 35 | `rosidl_typesupport_c` follows the recommended guidelines for ROS Core packages in the [ROS 2 Developer Guide](https://docs.ros.org/en/rolling/Contributing/Developer-Guide.html#quality-practices). 36 | 37 | ### Change Requests [2.i] 38 | 39 | This package requires that all changes occur through a pull request. 40 | 41 | ### Contributor Origin [2.ii] 42 | 43 | This package uses DCO as its confirmation of contributor origin policy. 44 | More information can be found in [CONTRIBUTING](../CONTRIBUTING.md). 45 | 46 | ### Peer Review Policy [2.iii] 47 | 48 | Following the recommended guidelines for ROS Core packages, all pull request have at least 1 peer review. 49 | 50 | ### Continuous Integration [2.iv] 51 | 52 | All pull request must pass CI on all [tier 1 platforms](https://www.ros.org/reps/rep-2000.html#support-tiers) 53 | 54 | Currently nightly results can be seen here: 55 | * [linux-aarch64_release](https://ci.ros2.org/view/nightly/job/nightly_linux-aarch64_release/lastBuild/testReport/rosidl_typesupport_c/) 56 | * [linux_release](https://ci.ros2.org/view/nightly/job/nightly_linux_release/lastBuild/testReport/rosidl_typesupport_c/) 57 | * [mac_osx_release](https://ci.ros2.org/view/nightly/job/nightly_osx_release/lastBuild/testReport/rosidl_typesupport_c/) 58 | * [windows_release](https://ci.ros2.org/view/nightly/job/nightly_win_rel/lastBuild/testReport/rosidl_typesupport_c/) 59 | 60 | ### Documentation Policy [2.v] 61 | 62 | All pull requests must resolve related documentation changes before merging. 63 | 64 | ## Documentation [3] 65 | 66 | ### Feature Documentation [3.i] 67 | 68 | `rosidl_typesupport_c` has feature documentation and it is publicly [hosted](docs/FEATURES.md). 69 | 70 | ### Public API Documentation [3.ii] 71 | 72 | `rosidl_typesupport_c` has documentation of its public API, and it is publicly [hosted](http://docs.ros2.org/latest/api/rosidl_typesupport_c/index.html). 73 | 74 | ### License [3.iii] 75 | 76 | The license for `rosidl_typesupport_c` is Apache 2.0, and a summary is in each source file, the type is declared in the [package.xml](package.xml) manifest file, and a full copy of the license is in the [LICENSE](../LICENSE) file. 77 | 78 | There is an automated test which runs a linter that ensures each file has a license statement. 79 | 80 | Most recent test results can be found [here](http://ci.ros2.org/job/nightly_linux_release/lastBuild/testReport/rosidl_typesupport_c/copyright). 81 | 82 | ### Copyright Statements [3.iv] 83 | 84 | The copyright holders each provide a statement of copyright in each source code file in `rosidl_typesupport_c`. 85 | 86 | There is an automated test which runs a linter that ensures each file has at least one copyright statement. 87 | 88 | Most recent test results can be found [here](http://ci.ros2.org/job/nightly_linux_release/lastBuild/testReport/rosidl_typesupport_c/copyright). 89 | 90 | ## Testing [4] 91 | 92 | ### Feature Testing [4.i] 93 | 94 | The features of `rosidl_typesupport_c` are tested, and their tests are located in the [test directory](https://github.com/ros2/rosidl_typesupport/tree/master/rosidl_typesupport_c/test). 95 | 96 | Most recent test results can be found [here](https://ci.ros2.org/job/nightly_linux_release/lastBuild/testReport/rosidl_typesupport_c). 97 | 98 | ### Public API Testing [4.ii] 99 | 100 | The public API of `rosidl_typesupport_c` is tested, and the tests are located in the [test directory](https://github.com/ros2/rosidl_typesupport/tree/master/rosidl_typesupport_c/test). 101 | 102 | Most recent test results can be found [here](https://ci.ros2.org/job/nightly_linux_release/lastBuild/testReport/rosidl_typesupport_c). 103 | 104 | ### Coverage [4.iv] 105 | 106 | `rosidl_typesupport_c` follows the recommendations for ROS Core packages in the [ROS 2 Developer Guide](https://docs.ros.org/en/rolling/Contributing/Developer-Guide.html#code-coverage), and opts to use line coverage instead of branch coverage. 107 | 108 | This includes: 109 | 110 | - tracking and reporting line coverage statistics 111 | - achieving and maintaining a reasonable branch line coverage (90-100%) 112 | - no lines are manually skipped in coverage calculations 113 | 114 | Changes are required to make a best effort to keep or increase coverage before being accepted, but decreases are allowed if properly justified and accepted by reviewers. 115 | 116 | Current coverage statistics can be viewed [here](https://ci.ros2.org/job/nightly_linux_coverage/lastSuccessfulBuild/cobertura/src_ros2_rosidl_typesupport_rosidl_typesupport_c_src/). A description of how coverage statistics are calculated is summarized in this page ["ROS 2 Onboarding Guide"](https://docs.ros.org/en/rolling/Contributing/Developer-Guide.html#note-on-coverage-runs). 117 | 118 | ### Performance [4.iv] 119 | 120 | `rosidl_typesupport_c` follows the recommendations for performance testing of C code in the [ROS 2 Developer Guide](https://docs.ros.org/en/rolling/Contributing/Developer-Guide.html#performance), and opts to do performance analysis on each release rather than each change. 121 | 122 | Package level and system level performance benchmarks that cover features of `rosidl_typesupport_c` can be found at: 123 | * [Benchmarks](http://build.ros2.org/view/Rci/job/Rci__benchmark_ubuntu_focal_amd64/BenchmarkTable/) 124 | * [Performance](http://build.ros2.org/view/Rci/job/Rci__nightly-performance_ubuntu_focal_amd64/lastCompletedBuild/) 125 | 126 | Changes that introduce regressions in performance must be adequately justified in order to be accepted and merged. 127 | 128 | ### Linters and Static Analysis [4.v] 129 | 130 | `rosidl_typesupport_c` uses and passes all the standard linters and static analysis tools for a C package as described in the [ROS 2 Developer Guide](https://docs.ros.org/en/rolling/Contributing/Developer-Guide.html#linters-and-static-analysis). 131 | 132 | Results of the linting tests can be found [here](https://ci.ros2.org/job/nightly_linux_release/lastBuild/testReport/rosidl_typesupport_c/). 133 | 134 | ## Dependencies [5] 135 | 136 | ### Direct Runtime ROS Dependencies [5.i/5.ii] 137 | 138 | `rosidl_typesupport_c` has the following runtime ROS dependencies, all of which are at **Quality Level 1** 139 | * `rcpputils`: [QUALITY DECLARATION](https://github.com/ros2/rcpputils/tree/master/QUALITY_DECLARATION.md) 140 | * `rosidl_runtime_c`: [QUALITY DECLARATION](https://github.com/ros2/rosidl/tree/master/rosidl_runtime_c/QUALITY_DECLARATION.md) 141 | * `rosidl_typesupport_interface`: [QUALITY DECLARATION](https://github.com/ros2/rosidl/tree/master/rosidl_typesupport_interface/QUALITY_DECLARATION.md) 142 | 143 | It has "buildtool" dependencies, which do not affect the resulting quality of the package, because they do not contribute to the public library API. 144 | It also has several test dependencies, which do not affect the resulting quality of the package, because they are only used to build and run the test code. 145 | 146 | ### Direct Runtime Non-ROS Dependencies [5.iii] 147 | 148 | `rosidl_typesupport_c` does not have any runtime non-ROS dependencies. 149 | 150 | ## Platform Support [6] 151 | 152 | `rosidl_typesupport_c` supports all of the tier 1 platforms as described in [REP-2000](https://www.ros.org/reps/rep-2000.html#support-tiers), and tests each change against all of them. 153 | 154 | Currently nightly results can be seen here: 155 | * [linux-aarch64_release](https://ci.ros2.org/view/nightly/job/nightly_linux-aarch64_release/lastBuild/testReport/rosidl_typesupport_c/) 156 | * [linux_release](https://ci.ros2.org/view/nightly/job/nightly_linux_release/lastBuild/testReport/rosidl_typesupport_c/) 157 | * [mac_osx_release](https://ci.ros2.org/view/nightly/job/nightly_osx_release/lastBuild/testReport/rosidl_typesupport_c/) 158 | * [windows_release](https://ci.ros2.org/view/nightly/job/nightly_win_rel/lastBuild/testReport/rosidl_typesupport_c/) 159 | 160 | ## Security [7] 161 | 162 | ### Vulnerability Disclosure Policy [7.i] 163 | 164 | This package conforms to the Vulnerability Disclosure Policy in [REP-2006](https://www.ros.org/reps/rep-2006.html). 165 | -------------------------------------------------------------------------------- /rosidl_typesupport_tests/test/rosidl_typesupport_c/test_service_typesupport.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | #include "gtest/gtest.h" 20 | 21 | #include "rcutils/allocator.h" 22 | #include "rcutils/env.h" 23 | 24 | #include "rosidl_runtime_c/string_functions.h" 25 | 26 | #include "rosidl_typesupport_tests/action/fibonacci.h" 27 | #include "rosidl_typesupport_tests/srv/basic_types.h" 28 | 29 | #include "rmw/rmw.h" 30 | 31 | TEST(test_service_typesupport, event_message_create_and_destroy_invalid_arguments) 32 | { 33 | rcutils_allocator_t allocator = rcutils_get_default_allocator(); 34 | // *INDENT-OFF* 35 | const rosidl_service_type_support_t * srv_ts = 36 | rosidl_typesupport_c__get_service_type_support_handle__rosidl_typesupport_tests__srv__BasicTypes(); // NOLINT 37 | // *INDENT-ON* 38 | 39 | rosidl_service_introspection_info_t valid_info; 40 | 41 | // null info 42 | EXPECT_EQ( 43 | nullptr, 44 | srv_ts->event_message_create_handle_function(nullptr, &allocator, nullptr, nullptr)); 45 | // null allocator 46 | EXPECT_EQ( 47 | nullptr, 48 | srv_ts->event_message_create_handle_function(&valid_info, nullptr, nullptr, nullptr)); 49 | } 50 | 51 | TEST(test_service_typesupport, basic_types_event_message_create) 52 | { 53 | rcutils_allocator_t allocator = rcutils_get_default_allocator(); 54 | // *INDENT-OFF* 55 | const rosidl_service_type_support_t * srv_ts = 56 | rosidl_typesupport_c__get_service_type_support_handle__rosidl_typesupport_tests__srv__BasicTypes(); // NOLINT 57 | 58 | const rosidl_message_type_support_t * msg_ts = 59 | rosidl_typesupport_c__get_message_type_support_handle__rosidl_typesupport_tests__srv__BasicTypes_Event(); // NOLINT 60 | // *INDENT-ON* 61 | 62 | if (std::string(rmw_get_implementation_identifier()).find("rmw_cyclonedds") == 0) { 63 | EXPECT_STREQ( 64 | srv_ts->typesupport_identifier, 65 | "rosidl_typesupport_introspection_c"); 66 | EXPECT_STREQ( 67 | msg_ts->typesupport_identifier, 68 | "rosidl_typesupport_introspection_c"); 69 | } else { 70 | EXPECT_STREQ(srv_ts->typesupport_identifier, "rosidl_typesupport_c"); 71 | EXPECT_STREQ(msg_ts->typesupport_identifier, "rosidl_typesupport_c"); 72 | } 73 | 74 | EXPECT_EQ(srv_ts->event_typesupport, msg_ts); 75 | 76 | rosidl_service_introspection_info_t expected_info; 77 | expected_info.sequence_number = 2; 78 | expected_info.event_type = 2; 79 | expected_info.stamp_nanosec = 123; 80 | expected_info.stamp_sec = 123; 81 | auto gid = std::array{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; 82 | std::copy(gid.begin(), gid.end(), expected_info.client_gid); 83 | 84 | rosidl_typesupport_tests__srv__BasicTypes_Request expected_request; 85 | rosidl_typesupport_tests__srv__BasicTypes_Request__init(&expected_request); 86 | expected_request.int16_value = -1; 87 | expected_request.uint16_value = 123; 88 | rosidl_typesupport_tests__srv__BasicTypes_Response expected_response; 89 | rosidl_typesupport_tests__srv__BasicTypes_Response__init(&expected_response); 90 | expected_response.bool_value = true; 91 | rosidl_runtime_c__String__assign(&expected_response.string_value, "hello world"); 92 | 93 | // null request and response arguments 94 | { 95 | auto * event = static_cast( 96 | srv_ts->event_message_create_handle_function(&expected_info, &allocator, nullptr, nullptr)); // NOLINT 97 | ASSERT_NE(event, nullptr); 98 | EXPECT_EQ(event->info.sequence_number, expected_info.sequence_number); 99 | EXPECT_EQ(event->info.event_type, expected_info.event_type); 100 | EXPECT_EQ(event->info.stamp.nanosec, expected_info.stamp_nanosec); 101 | EXPECT_EQ(event->info.stamp.sec, expected_info.stamp_sec); 102 | for (int i = 0; i < 16; ++i) { 103 | EXPECT_EQ(event->info.client_gid[i], expected_info.client_gid[i]); 104 | } 105 | EXPECT_EQ(event->request.size, 0U); 106 | EXPECT_EQ(event->response.size, 0U); 107 | 108 | ASSERT_TRUE(srv_ts->event_message_destroy_handle_function(event, &allocator)); 109 | } 110 | 111 | // request argument set, null response argument 112 | { 113 | auto * event = static_cast( 114 | srv_ts->event_message_create_handle_function( 115 | &expected_info, 116 | &allocator, 117 | static_cast(&expected_request), 118 | nullptr)); 119 | ASSERT_NE(event, nullptr); 120 | EXPECT_EQ(event->info.sequence_number, expected_info.sequence_number); 121 | EXPECT_EQ(event->info.event_type, expected_info.event_type); 122 | EXPECT_EQ(event->info.stamp.nanosec, expected_info.stamp_nanosec); 123 | EXPECT_EQ(event->info.stamp.sec, expected_info.stamp_sec); 124 | for (int i = 0; i < 16; ++i) { 125 | EXPECT_EQ(event->info.client_gid[i], expected_info.client_gid[i]); 126 | } 127 | ASSERT_EQ(event->request.size, 1U); 128 | EXPECT_EQ(event->response.size, 0U); 129 | EXPECT_EQ(event->request.data[0].int16_value, expected_request.int16_value); 130 | EXPECT_EQ(event->request.data[0].uint16_value, expected_request.uint16_value); 131 | ASSERT_TRUE(srv_ts->event_message_destroy_handle_function(event, &allocator)); 132 | } 133 | 134 | // response argument set, null request argument 135 | { 136 | auto * event = static_cast( 137 | srv_ts->event_message_create_handle_function( 138 | &expected_info, 139 | &allocator, 140 | nullptr, 141 | static_cast(&expected_response))); 142 | 143 | ASSERT_NE(event, nullptr); 144 | EXPECT_EQ(event->info.sequence_number, expected_info.sequence_number); 145 | EXPECT_EQ(event->info.event_type, expected_info.event_type); 146 | EXPECT_EQ(event->info.stamp.nanosec, expected_info.stamp_nanosec); 147 | EXPECT_EQ(event->info.stamp.sec, expected_info.stamp_sec); 148 | for (int i = 0; i < 16; ++i) { 149 | EXPECT_EQ(event->info.client_gid[i], expected_info.client_gid[i]); 150 | } 151 | EXPECT_EQ(event->request.size, 0U); 152 | ASSERT_EQ(event->response.size, 1U); 153 | EXPECT_EQ(event->response.data[0].bool_value, expected_response.bool_value); 154 | EXPECT_TRUE( 155 | rosidl_runtime_c__String__are_equal( 156 | &event->response.data[0].string_value, &expected_response.string_value)); 157 | ASSERT_TRUE(srv_ts->event_message_destroy_handle_function(event, &allocator)); 158 | } 159 | 160 | // both request and response arguments set 161 | { 162 | auto * event = static_cast( 163 | srv_ts->event_message_create_handle_function( 164 | &expected_info, 165 | &allocator, 166 | static_cast(&expected_request), 167 | static_cast(&expected_response))); 168 | 169 | ASSERT_NE(event, nullptr); 170 | EXPECT_EQ(event->info.sequence_number, expected_info.sequence_number); 171 | EXPECT_EQ(event->info.event_type, expected_info.event_type); 172 | EXPECT_EQ(event->info.stamp.nanosec, expected_info.stamp_nanosec); 173 | EXPECT_EQ(event->info.stamp.sec, expected_info.stamp_sec); 174 | for (int i = 0; i < 16; ++i) { 175 | EXPECT_EQ(event->info.client_gid[i], expected_info.client_gid[i]); 176 | } 177 | ASSERT_EQ(event->request.size, 1U); 178 | EXPECT_EQ(event->request.data[0].int16_value, expected_request.int16_value); 179 | EXPECT_EQ(event->request.data[0].uint16_value, expected_request.uint16_value); 180 | ASSERT_EQ(event->response.size, 1U); 181 | EXPECT_EQ(event->response.data[0].bool_value, expected_response.bool_value); 182 | EXPECT_TRUE( 183 | rosidl_runtime_c__String__are_equal( 184 | &event->response.data[0].string_value, &expected_response.string_value)); 185 | ASSERT_TRUE(srv_ts->event_message_destroy_handle_function(event, &allocator)); 186 | } 187 | } 188 | 189 | TEST(test_service_typesupport, fibonacci_action_services_event) 190 | { 191 | // *INDENT-OFF* 192 | const rosidl_message_type_support_t * send_goal_event_msg_ts = 193 | rosidl_typesupport_c__get_message_type_support_handle__rosidl_typesupport_tests__action__Fibonacci_SendGoal_Event(); // NOLINT 194 | const rosidl_message_type_support_t * get_result_event_msg_ts = 195 | rosidl_typesupport_c__get_message_type_support_handle__rosidl_typesupport_tests__action__Fibonacci_GetResult_Event(); // NOLINT 196 | // *INDENT-ON* 197 | 198 | ASSERT_NE(nullptr, send_goal_event_msg_ts); 199 | ASSERT_NE(nullptr, get_result_event_msg_ts); 200 | 201 | if (std::string(rmw_get_implementation_identifier()).find("rmw_cyclonedds") == 0) { 202 | EXPECT_STREQ( 203 | send_goal_event_msg_ts->typesupport_identifier, 204 | "rosidl_typesupport_introspection_c"); 205 | EXPECT_STREQ( 206 | get_result_event_msg_ts->typesupport_identifier, 207 | "rosidl_typesupport_introspection_c"); 208 | } else { 209 | EXPECT_STREQ(send_goal_event_msg_ts->typesupport_identifier, "rosidl_typesupport_c"); 210 | EXPECT_STREQ(get_result_event_msg_ts->typesupport_identifier, "rosidl_typesupport_c"); 211 | } 212 | } 213 | -------------------------------------------------------------------------------- /rosidl_typesupport_cpp/QUALITY_DECLARATION.md: -------------------------------------------------------------------------------- 1 | This document is a declaration of software quality for the `rosidl_typesupport_cpp` package, based on the guidelines in [REP-2004](https://www.ros.org/reps/rep-2004.html). 2 | 3 | # rosidl_typesupport_cpp Quality Declaration 4 | 5 | The package `rosidl_typesupport_cpp` claims to be in the **Quality Level 1** category. 6 | 7 | Below are the rationales, notes, and caveats for this claim, organized by each requirement listed in the [Package Requirements for Quality Level 1 in REP-2004](https://www.ros.org/reps/rep-2004.html). 8 | 9 | ## Version Policy [1] 10 | 11 | ### Version Scheme [1.i] 12 | 13 | `rosidl_typesupport_cpp` uses `semver` according to the recommendation for ROS Core packages in the [ROS 2 Developer Guide](https://docs.ros.org/en/rolling/Contributing/Developer-Guide.html#versioning). 14 | 15 | ### Version Stability [1.ii] 16 | 17 | `rosidl_typesupport_cpp` is at a stable version, i.e. >= 1.0.0. The current version can be found in its [package.xml](./package.xml), and its change history can be found in its [CHANGELOG](./CHANGELOG.rst). 18 | 19 | ### Public API Declaration [1.iii] 20 | 21 | All symbols in the installed headers are considered part of the public API. 22 | 23 | All installed headers are in the `include` directory of the package, headers in any other folders are not installed and considered private. 24 | 25 | ### API Stability Within a Released ROS Distribution [1.iv]/[1.vi] 26 | 27 | `rosidl_typesupport_cpp` will not break public API within a released ROS distribution, i.e. no major releases once the ROS distribution is released. 28 | 29 | ### ABI Stability Within a Released ROS Distribution [1.v]/[1.vi] 30 | 31 | `rosidl_typesupport_cpp` contains C++ code and therefore must be concerned with ABI stability, and will maintain ABI stability within a ROS distribution. 32 | 33 | ## Change Control Process [2] 34 | 35 | `rosidl_typesupport_cpp` follows the recommended guidelines for ROS Core packages in the [ROS 2 Developer Guide](https://docs.ros.org/en/rolling/Contributing/Developer-Guide.html#quality-practices). 36 | 37 | ### Change Requests [2.i] 38 | 39 | This package requires that all changes occur through a pull request. 40 | 41 | ### Contributor Origin [2.ii] 42 | 43 | This package uses DCO as its confirmation of contributor origin policy. 44 | More information can be found in [CONTRIBUTING](../CONTRIBUTING.md). 45 | 46 | ### Peer Review Policy [2.iii] 47 | 48 | Following the recommended guidelines for ROS Core packages, all pull requests must have at least 1 peer review. 49 | 50 | ### Continuous Integration [2.iv] 51 | 52 | All pull request must pass CI on all [tier 1 platforms](https://www.ros.org/reps/rep-2000.html#support-tiers) 53 | 54 | Currently nightly results for the master branch can be seen here: 55 | * [linux-aarch64_release](https://ci.ros2.org/view/nightly/job/nightly_linux-aarch64_release/lastBuild/testReport/rosidl_typesupport_cpp/) 56 | * [linux_release](https://ci.ros2.org/view/nightly/job/nightly_linux_release/lastBuild/testReport/rosidl_typesupport_cpp/) 57 | * [mac_osx_release](https://ci.ros2.org/view/nightly/job/nightly_osx_release/lastBuild/testReport/rosidl_typesupport_cpp/) 58 | * [windows_release](https://ci.ros2.org/view/nightly/job/nightly_win_rel/lastBuild/testReport/rosidl_typesupport_cpp/) 59 | 60 | ### Documentation Policy [2.v] 61 | 62 | All pull requests must resolve related documentation changes before merging. 63 | 64 | ## Documentation [3] 65 | 66 | ### Feature Documentation [3.i] 67 | 68 | `rosidl_typesupport_cpp` has feature documentation and it is publicly [hosted](docs/FEATURES.md). 69 | 70 | ### Public API Documentation [3.ii] 71 | 72 | `rosidl_typesupport_cpp` has documentation of its public API, and it is publicly [hosted](http://docs.ros2.org/latest/api/rosidl_typesupport_cpp/index.html). 73 | 74 | ### License [3.iii] 75 | 76 | The license for `rosidl_typesupport_cpp` is Apache 2.0, and a summary is in each source file, the type is declared in the [package.xml](package.xml) manifest file, and a full copy of the license is in the [LICENSE](./LICENSE) file. 77 | 78 | There is an automated test which runs a linter that ensures each file has a license statement. 79 | 80 | Most recent test results can be found [here](http://ci.ros2.org/job/nightly_linux_release/lastBuild/testReport/rosidl_typesupport_cpp/copyright). 81 | 82 | ### Copyright Statements [3.iv] 83 | 84 | The copyright holders each provide a statement of copyright in each source code file in `rosidl_typesupport_cpp`. 85 | 86 | There is an automated test which runs a linter that ensures each file has at least one copyright statement. 87 | 88 | Most recent test results can be found [here](http://ci.ros2.org/job/nightly_linux_release/lastBuild/testReport/rosidl_typesupport_cpp/copyright). 89 | 90 | ## Testing [4] 91 | 92 | ### Feature Testing [4.i] 93 | 94 | The features of `rosidl_typesupport_cpp` are tested, and their tests are located in the [test directory](https://github.com/ros2/rosidl_typesupport/tree/master/rosidl_typesupport_cpp/test). 95 | 96 | Most recent test results can be found [here](https://ci.ros2.org/job/nightly_linux_release/lastBuild/testReport/rosidl_typesupport_cpp). 97 | 98 | ### Public API Testing [4.ii] 99 | 100 | The public API of `rosidl_typesupport_cpp` is tested, and the tests are located in the [test directory](https://github.com/ros2/rosidl_typesupport/tree/master/rosidl_typesupport_cpp/test). 101 | 102 | Most recent test results can be found [here](https://ci.ros2.org/job/nightly_linux_release/lastBuild/testReport/rosidl_typesupport_cpp). 103 | 104 | ### Coverage [4.iii] 105 | 106 | `rosidl_typesupport_cpp` follows the recommendations for ROS Core packages in the [ROS 2 Developer Guide](https://docs.ros.org/en/rolling/Contributing/Developer-Guide.html#code-coverage), and opts to use line coverage instead of branch coverage. 107 | 108 | This includes: 109 | 110 | - tracking and reporting line coverage statistics 111 | - achieving and maintaining a reasonable branch line coverage (90-100%) 112 | - no lines are manually skipped in coverage calculations 113 | 114 | Changes are required to make a best effort to keep or increase coverage before being accepted, but decreases are allowed if properly justified and accepted by reviewers. 115 | 116 | Current coverage statistics can be viewed [here](https://ci.ros2.org/job/nightly_linux_coverage/lastSuccessfulBuild/cobertura/src_ros2_rosidl_typesupport_rosidl_typesupport_cpp_src/). A description of how coverage statistics are calculated is summarized in this page ["ROS 2 Onboarding Guide"](https://docs.ros.org/en/rolling/Contributing/Developer-Guide.html#note-on-coverage-runs). 117 | 118 | ### Performance [4.iv] 119 | 120 | `rosidl_typesupport_cpp` follows the recommendations for performance testing of C/C++ code in the [ROS 2 Developer Guide](https://docs.ros.org/en/rolling/Contributing/Developer-Guide.html#performance), and opts to do performance analysis on each release rather than each change. 121 | 122 | Package level and system level benchmarks that cover features of `rosidl_typesupport_cpp` can be found at: 123 | * [Benchmarks](http://build.ros2.org/view/Rci/job/Rci__benchmark_ubuntu_focal_amd64/BenchmarkTable/) 124 | * [Performance](http://build.ros2.org/view/Rci/job/Rci__nightly-performance_ubuntu_focal_amd64/lastCompletedBuild/) 125 | 126 | Changes that introduce regressions in performance must be adequately justified in order to be accepted and merged. 127 | 128 | ### Linters and Static Analysis [4.v] 129 | 130 | `rosidl_typesupport_cpp` uses and passes all the standard linters and static analysis tools for a C++ package as described in the [ROS 2 Developer Guide](https://docs.ros.org/en/rolling/Contributing/Developer-Guide.html#linters-and-static-analysis). 131 | 132 | Results of the linting tests can be found [here](https://ci.ros2.org/job/nightly_linux_release/lastBuild/testReport/rosidl_typesupport_cpp/). 133 | 134 | ## Dependencies [5] 135 | 136 | ### Direct and Optional Runtime ROS Dependencies [5.i/5.ii] 137 | 138 | `rosidl_typesupport_cpp` has the following runtime ROS dependencies, all of which are at **Quality Level 1** 139 | * `rcpputils`: [QUALITY DECLARATION](https://github.com/ros2/rcpputils/tree/master/QUALITY_DECLARATION.md) 140 | * `rosidl_runtime_c`: [QUALITY DECLARATION](https://github.com/ros2/rosidl/tree/master/rosidl_runtime_c/QUALITY_DECLARATION.md) 141 | * `rosidl_runtime_cpp`: [QUALITY DECLARATION](https://github.com/ros2/rosidl/tree/master/rosidl_runtime_cpp/QUALITY_DECLARATION.md) 142 | * `rosidl_typesupport_c`: [QUALITY DECLARATION](../rosidl_typesupport_c/QUALITY_DECLARATION.md) 143 | * `rosidl_typesupport_interface`: [QUALITY DECLARATION](https://github.com/ros2/rosidl/tree/master/rosidl_typesupport_interface/QUALITY_DECLARATION.md) 144 | 145 | It has "buildtool" dependencies, which do not affect the resulting quality of the package, because they do not contribute to the public library API. 146 | It also has several test dependencies, which do not affect the resulting quality of the package, because they are only used to build and run the test code. 147 | 148 | ### Direct Runtime Non-ROS Dependencies [5.iii] 149 | 150 | `rosidl_typesupport_cpp` does not have any runtime non-ROS dependencies. 151 | 152 | ## Platform Support [6] 153 | 154 | `rosidl_typesupport_cpp` supports all of the tier 1 platforms as described in [REP-2000](https://www.ros.org/reps/rep-2000.html#support-tiers), and tests each change against all of them. 155 | 156 | Currently nightly results can be seen here: 157 | * [linux-aarch64_release](https://ci.ros2.org/view/nightly/job/nightly_linux-aarch64_release/lastBuild/testReport/rosidl_typesupport_cpp/) 158 | * [linux_release](https://ci.ros2.org/view/nightly/job/nightly_linux_release/lastBuild/testReport/rosidl_typesupport_cpp/) 159 | * [mac_osx_release](https://ci.ros2.org/view/nightly/job/nightly_osx_release/lastBuild/testReport/rosidl_typesupport_cpp/) 160 | * [windows_release](https://ci.ros2.org/view/nightly/job/nightly_win_rel/lastBuild/testReport/rosidl_typesupport_cpp/) 161 | 162 | ## Security [7] 163 | 164 | ### Vulnerability Disclosure Policy [7.i] 165 | 166 | This package conforms to the Vulnerability Disclosure Policy in [REP-2006](https://www.ros.org/reps/rep-2006.html). 167 | --------------------------------------------------------------------------------