通信中间件 Fast DDS(三) :fastddsgen的安装与使用
目录
1.fastddsgen介绍
2.fastddsgen的安装
2.1.Java的环境安装
2.2.Maven的安装
2.3.fastddsgen安装
2.3.1.window的源码安装
2.3.2.windows使用vcpkg安装
2.3.3.Linux安装
3.fastddsgen的使用
4.1.创建 IDL 文件
4.2.生成代码
4.3.生成的文件
4.5.常用命令选项
4.6.复杂 IDL 示例
4.7.在 CMake 项目中集成
4.8.实际项目示例
4.9.故障排除
4.总结
1.fastddsgen介绍
fastddsgen
是 FastDDS 官方提供的 IDL(Interface Definition Language)编译器,用于将 IDL 定义的数据类型转换为 FastDDS 兼容的代码(支持 C++、Python 等语言),自动生成数据序列化 / 反序列化逻辑、类型注册代码等,是 FastDDS 开发的基础工具。
在 FastDDS 中,节点间通信的数据结构需通过 IDL 定义(类似接口契约或通信协议之类的),fastddsgen
的核心功能是:
- 将 IDL 中的结构体(
struct
)、枚举(enum
)等类型转换为目标语言的代码; - 自动生成数据的序列化(将数据转为字节流)和反序列化(将字节流还原为数据)逻辑;
- 生成类型注册相关代码(让 FastDDS 识别自定义数据类型)。
举个例子,比如定义了如下数据结构:HelloWorld.idl
struct HelloWorld
{unsigned long index;string message;
};
通过fastddsgen自动生成改数据结构的序列化和反序列化代码以及Fast DDS 兼容的发布者/订阅者代码,执行如下命令:
则会生成:
具体文件的作用会在后面章节详解。
2.fastddsgen的安装
fastddsgen
基于 Java 开发,需依赖 JDK 8+ 和 Maven(编译源码时需要)
2.1.Java的环境安装
JDK 8 及以上:fastddsgen 基于 Java 开发,需安装 JDK(推荐 OpenJDK 11)。
下载 OpenJDK 11 并安装,配置环境变量 JAVA_HOME
(指向 JDK 安装目录),并将 %JAVA_HOME%\bin
添加到 PATH
。
具体的下载地址:https://adoptium.net/zh-CN/temurin/releases?version=11&os=any&arch=any
根据自己的系统下载合适的版本,我是在windows11系统上安装的,下载的是windows的安装程序OpenJDK11U-jdk_x64_windows_hotspot_11.0.28_6.msi:
安装后此安装程序会把java的路径自动加到系统的环境变量中, 验证是否安装成功,在命令行执行:
2.2.Maven的安装
Maven的下载地址:
https://maven.apache.org/download.cgi
选择下面版本:
解压后配置 MAVEN_HOME
环境变量,将 %MAVEN_HOME%\bin
添加到 PATH
。一般需要安装在没有中文的目录下面:
验证 Maven 安装:
2.3.fastddsgen安装
2.3.1.window的源码安装
1.拉取 fastddsgen 源码
https://github.com/eProsima/Fast-DDS-Gen.git
2.编译构建
在fastddsgen的根目录下执行:
./gradlew assemble
但是在我的电脑上一直提示这个:
好像是下载gradle-7.6-bin.zip失败,尝试很多遍之后,把这个地址复制到浏览器看是否可以下载呢?结果可以,下载完gradle-7.6-bin.zip,但是在这里提示还是下载失败,怎么使用本地的gradle-7.6-bin.zip编译呢?于是想到:
fastddsgen 若在构建过程中依赖 Gradle(部分版本或子模块可能使用 Gradle 管理),且需要指定本地已下载的 gradle-7.6-bin.zip
避免重新下载,核心是利用 Gradle Wrapper 的本地缓存机制—— 将本地压缩包放入 Gradle 的分发缓存目录,Gradle 会自动识别并使用本地文件,无需重复下载。
具体步骤(Windows 系统为例)
1)找到 Gradle 分发缓存目录
Gradle Wrapper 会将下载的 Gradle 压缩包缓存到以下路径:
C:\Users\<你的用户名>\.gradle\wrapper\dists\gradle-7.6-bin\<随机哈希目录>
<你的用户名>
:即 Windows 登录用户名(如Administrator
或你的账号名)。<随机哈希目录>
:Gradle 自动生成的唯一目录(如xxxxxxxxx
,由 Gradle 基于版本号计算,确保唯一性)。
我的电脑就是这个目录:
C:\Users\Administrator\.gradle\wrapper\dists\gradle-7.6-bin\9l9tetv7ltxvx3i8an4pb86ye
把刚下载好的gradle-7.6-bin.zip放到此目录下,
重新执行构建命令:
然后把D:\OpenProject\Fast-DDS-Gen\scripts加到系统的环境变量中:
验证安装是否成功:
2.3.2.windows使用vcpkg安装
vcpkg install fastddsgen
2.3.3.Linux安装
方法1:从源码安装(推荐)
# 克隆 Fast DDS 仓库
git clone https://github.com/eProsima/Fast-DDS-Gen.git
cd Fast-DDS# 创建构建目录
mkdir build && cd build# 配置和编译
cmake -DCMAKE_INSTALL_PREFIX=/usr/local ..
make -j$(nproc)# 安装(包括 fastddsgen)
sudo make install
方法2:使用预编译二进制
# Ubuntu/Debian
sudo apt update
sudo apt-get install fastddsgen# 或者从 GitHub 发布页面下载
wget https://github.com/eProsima/Fast-DDS/releases/download/v2.10.0/fastddsgen-2.10.0-linux-x64.tar.gz
tar -xzf fastddsgen-2.10.0-linux-x64.tar.gz
sudo cp fastddsgen /usr/local/bin/
3.fastddsgen的使用
4.1.创建 IDL 文件
创建一个简单的 IDL 文件(如 HelloWorld.idl
),定义通信的数据结构:
struct HelloWorld
{unsigned long index;string message;
};
4.2.生成代码
# 基本生成
fastddsgen HelloWorld.idl# 生成并替换现有文件
fastddsgen -replace HelloWorld.idl# 指定输出目录
fastddsgen -d generated HelloWorld.idl# 生成示例代码
fastddsgen -example CMake HelloWorld.idl
在生成代码的过程中(windows11+vs2022),遇到一个问题:
C:\Users\Administrator>fastddsgen D:\OpenProject\Fast-DDS\examples\cpp\hello_tcp\Message.idl
Processing the file D:\OpenProject\Fast-DDS\examples\cpp\hello_tcp\Message.idl...
ERROR<callPreprocessor>: Cannot execute the preprocessor. Reason: Cannot run program "cl.exe": CreateProcess error=2, 系统找不到指定的文件。
这个错误的原因是 fastddsgen 需要调用 C 预处理器(cl.exe),但系统中未找到该程序。cl.exe
是微软 Visual Studio 的 C/C++ 编译器,属于 Visual Studio 的 “C++ 生成工具” 组件,需安装并配置环境后才能使用。
解决方法1:用 Visual Studio 命令提示符运行 fastddsgen
cl.exe
的路径默认不会添加到系统全局 PATH
中,需通过 Visual Studio 自带的命令提示符 启动,该窗口会自动配置编译环境:
按下 Win
键,搜索并打开 “x64 Native Tools Command Prompt for VS 2022”(根据你的 VS 版本选择,如 2019/2022):
在该窗口中,重新执行你的 fastddsgen 命令:
fastddsgen D:\OpenProject\Fast-DDS\examples\cpp\hello_tcp\HelloWorld.idl
解决方法2:(可选)手动添加 cl.exe 到系统 PATH(不推荐,易冲突)
若需在普通命令提示符中使用,可手动将 cl.exe
路径添加到系统 PATH
:
找到 cl.exe
的安装路径(根据 VS 版本和安装目录,示例路径):
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\bin\Hostx64\x64
(路径中的 14.36.32532
是版本号,可能因安装版本不同而变化,可在 VC\Tools\MSVC
目录下查找最新版本)。
将该路径添加到系统 PATH
环境变量(步骤同之前环境变量配置)。
4.3.生成的文件
运行后会生成以下文件:
-
HelloWorld.hpp
- 数据类型头文件 -
HelloWorldCdrAux.ipp和HelloWorldCdrAux.hpp
- 数据打包实现 -
HelloWorldPubSubTypes.h
- 发布/订阅类型支持头文件 -
HelloWorldPubSubTypes.cxx
- 发布/订阅类型支持实现 -
HelloWorldTypeObjectSupport.hpp: 用于动态类型元数据的生成、序列化和验证
-
HelloWorldTypeObjectSupport.cxx: 用于动态类型元数据的生成、序列化和验证
4.5.常用命令选项
# 显示帮助
fastddsgen -help# 常用选项
fastddsgen -replace -d output_dir -typeobject MyTypes.idl# 生成 CMake 项目示例
fastddsgen -example CMake -d examples ComplexType.idl# 指定不同的编码
fastddsgen -encoding UTF8 MyTypes.idl# 不生成已弃用的代码
fastddsgen -notypecode MyTypes.idl
完整选项列表:
选项 | 作用 | 示例 |
---|---|---|
-h / --help | 查看所有选项的帮助说明 | fastddsgen -h |
--version | 查看 fastddsgen 版本 | fastddsgen --version |
-d <目录> | 指定代码输出目录(默认当前目录) | fastddsgen -d ./generated HelloWorld.idl |
-replace | 覆盖已存在的生成文件(默认不覆盖) | fastddsgen -replace HelloWorld.idl |
-language <语言> | 指定生成代码的语言(默认 C++ ) | fastddsgen -language Python HelloWorld.idl |
-typeobject | 生成动态类型(XTypes)支持文件(如 *TypeObjectSupport.* ) | fastddsgen -typeobject HelloWorld.idl |
-no-types | 仅生成类型注册代码,不生成结构体定义(适合已有结构体时) | fastddsgen -no-types HelloWorld.idl |
-example <语言> | 生成发布者 / 订阅者示例代码(支持 C++ /Python ) | fastddsgen -example C++ HelloWorld.idl |
-topic <名称> | 为示例代码指定 Topic 名称(默认用 IDL 结构体名) | fastddsgen -example C++ -topic MyTopic HelloWorld.idl |
-I <路径> | 添加 IDL 包含文件的搜索路径(类似 C++ 的 -I ) | fastddsgen -I ./include Common.idl |
-D <宏定义> | 定义预处理宏(类似 C++ 的 -D ) | fastddsgen -D DEBUG HelloWorld.idl |
-template <目录> | 使用自定义代码生成模板(覆盖默认模板) | fastddsgen -template ./my_templates HelloWorld.idl |
-namespace <名称> | 为生成的 C++ 代码指定命名空间(默认无) | fastddsgen -namespace MyNS HelloWorld.idl |
-cs | 生成 C# 代码(实验性,需配合特定版本) | fastddsgen -cs HelloWorld.idl |
-java | 生成java 代码 | fastddsgen -java HelloWorld.idl |
常用组合示例
1.生成 C++ 代码 + 示例到指定目录:
fastddsgen -d ./output -example C++ -topic HelloTopic HelloWorld.idl
效果:在 ./output
目录生成 HelloWorld
的结构体代码、类型注册代码,以及带 HelloTopic
主题的发布者 / 订阅者示例。
2.处理包含其他 IDL 的文件:
若 HelloWorld.idl
中用 #include "Common.idl"
引用了其他 IDL,需指定包含路径:
fastddsgen -I ./idl_include HelloWorld.idl
3.生成动态类型支持文件:
fastddsgen -typeobject -example C++ HelloWorld.idl
效果:除常规代码外,额外生成 HelloWorldTypeObjectSupport.hpp
和 .cxx
,支持动态类型发现。
4.6.复杂 IDL 示例
1.复杂数据类型 IDL
module MyModule {// 枚举类型enum Color {RED,GREEN,BLUE};// 结构体包含数组和序列struct Vector3 {double x;double y;double z;};// 复杂结构体struct SensorData {unsigned long sensor_id;string sensor_name;Vector3 position;sequence<double> readings;Color led_color;};// 带键值的结构体(用于内容过滤)struct KeyedData {@key unsigned long id;string value;double timestamp;};// 联合类型union DataUnion switch (long) {case 0: long int_value;case 1: double double_value;case 2: string string_value;default: boolean bool_value;};
};
2.生成复杂类型
fastddsgen -replace -d generated -typeobject ComplexTypes.idl
4.7.在 CMake 项目中集成
1.基本的 CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(MyFastDDSProject)# 查找依赖
find_package(fastcdr REQUIRED)
find_package(fastrtps REQUIRED)
find_package(fastdds REQUIRED)# 查找 fastddsgen
find_program(FASTDDSGEN fastddsgen)
if(NOT FASTDDSGEN)message(FATAL_ERROR "fastddsgen not found")
endif()# 设置 IDL 文件
set(IDL_FILESHelloWorld.idlComplexTypes.idl
)# 生成代码
set(GENERATED_SOURCES "")
foreach(idl_file ${IDL_FILES})get_filename_component(target_name ${idl_file} NAME_WE)# 设置生成的文件路径set(gen_dir ${CMAKE_CURRENT_BINARY_DIR}/generated)set(gen_files ${gen_dir}/${target_name}.h${gen_dir}/${target_name}.cxx${gen_dir}/${target_name}PubSubTypes.h${gen_dir}/${target_name}PubSubTypes.cxx)# 添加自定义命令生成代码add_custom_command(OUTPUT ${gen_files}COMMAND ${FASTDDSGEN} -replace -d ${gen_dir} ${CMAKE_CURRENT_SOURCE_DIR}/${idl_file}DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${idl_file}COMMENT "Generating code for ${idl_file}")list(APPEND GENERATED_SOURCES ${gen_files})
endforeach()# 包含生成的头文件
include_directories(${CMAKE_CURRENT_BINARY_DIR}/generated${FASTCDR_INCLUDE_DIR}${FASTRTPS_INCLUDE_DIRS}
)# 创建可执行文件
add_executable(my_publishersrc/publisher_main.cpp${GENERATED_SOURCES}
)add_executable(my_subscribersrc/subscriber_main.cpp${GENERATED_SOURCES}
)# 链接库
target_link_libraries(my_publisherfastcdrfastrtpsfastdds
)target_link_libraries(my_subscriberfastcdrfastrtpsfastdds
)
2.高级 CMake 集成
# 自定义函数简化 IDL 生成
function(generate_dds_idl TARGET_NAME IDL_FILE)get_filename_component(name_we ${IDL_FILE} NAME_WE)set(gen_dir ${CMAKE_CURRENT_BINARY_DIR}/generated)set(gen_sources ${gen_dir}/${name_we}.cxx${gen_dir}/${name_we}PubSubTypes.cxx)set(gen_headers ${gen_dir}/${name_we}.h${gen_dir}/${name_we}PubSubTypes.h)add_custom_command(OUTPUT ${gen_sources} ${gen_headers}COMMAND ${FASTDDSGEN} -replace -d ${gen_dir} ${CMAKE_CURRENT_SOURCE_DIR}/${IDL_FILE}DEPENDS ${IDL_FILE}COMMENT "Generating DDS code from ${IDL_FILE}")target_sources(${TARGET_NAME} PRIVATE ${gen_sources})target_include_directories(${TARGET_NAME} PRIVATE ${gen_dir})
endfunction()# 使用示例
add_executable(my_app src/main.cpp)
generate_dds_idl(my_app HelloWorld.idl)
generate_dds_idl(my_app ComplexTypes.idl)
4.8.实际项目示例
1.项目结构
my_project/
├── CMakeLists.txt
├── idl/
│ ├── HelloWorld.idl
│ └── SensorData.idl
├── src/
│ ├── publisher.cpp
│ ├── subscriber.cpp
│ └── main.cpp
└── generated/ (自动生成)
2.构建脚本
#!/bin/bash
# build.shmkdir -p build
cd build# 配置项目
cmake -DCMAKE_BUILD_TYPE=Release ..# 编译
make -j$(nproc)echo "构建完成!"
4.9.故障排除
1.fastddsgen 未找到
# 解决方案:检查安装路径
which fastddsgen
# 或者
find /usr -name "fastddsgen" 2>/dev/null
2.IDL 语法错误
# 验证 IDL 语法
fastddsgen -verbose MyTypes.idl
3.生成的代码编译错误
# 确保 Fast DDS 版本匹配
fastddsgen -version
pkg-config --modversion fastdds
4.IDL文件编码
IDL 文件一般都使用 UTF-8 编码
4.总结
fastddsgen
是 FastDDS 开发的 “必经之路”,正确使用它可以大幅减少手动编写序列化和类型注册代码的工作量。实际开发中,建议结合 -example
参数生成示例代码,快速搭建通信框架。