目录
[4.1.创建 IDL 文件](#4.1.创建 IDL 文件)
[4.6.复杂 IDL 示例](#4.6.复杂 IDL 示例)
[4.7.在 CMake 项目中集成](#4.7.在 CMake 项目中集成)
1.fastddsgen介绍
fastddsgen
是 FastDDS 官方提供的 IDL(Interface Definition Language)编译器,用于将 IDL 定义的数据类型转换为 FastDDS 兼容的代码(支持 C++、Python 等语言),自动生成数据序列化 / 反序列化逻辑、类型注册代码等,是 FastDDS 开发的基础工具。
在 FastDDS 中,节点间通信的数据结构需通过 IDL 定义(类似接口契约或通信协议之类的),fastddsgen
的核心功能是:
- 将 IDL 中的结构体(
struct
)、枚举(enum
)等类型转换为目标语言的代码; - 自动生成数据的序列化(将数据转为字节流)和反序列化(将字节流还原为数据)逻辑;
- 生成类型注册相关代码(让 FastDDS 识别自定义数据类型)。
举个例子,比如定义了如下数据结构:HelloWorld.idl
cpp
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的下载地址:
选择下面版本:

解压后配置 MAVEN_HOME
环境变量,将 %MAVEN_HOME%\bin
添加到 PATH
。一般需要安装在没有中文的目录下面:


验证 Maven 安装:

2.3.fastddsgen安装
2.3.1.window的源码安装
1.拉取 fastddsgen 源码
2.编译构建
在fastddsgen的根目录下执行:
cpp
./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 压缩包缓存到以下路径:
cpp
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:从源码安装(推荐)
cpp
# 克隆 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:使用预编译二进制
cpp
# 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
),定义通信的数据结构:
cpp
struct HelloWorld
{
unsigned long index;
string message;
};
4.2.生成代码
cpp
# 基本生成
fastddsgen HelloWorld.idl
# 生成并替换现有文件
fastddsgen -replace HelloWorld.idl
# 指定输出目录
fastddsgen -d generated HelloWorld.idl
# 生成示例代码
fastddsgen -example CMake HelloWorld.idl
在生成代码的过程中(windows11+vs2022),遇到一个问题:
cpp
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 命令:
cpp
fastddsgen D:\OpenProject\Fast-DDS\examples\cpp\hello_tcp\HelloWorld.idl
解决方法2:(可选)手动添加 cl.exe 到系统 PATH(不推荐,易冲突)
若需在普通命令提示符中使用,可手动将 cl.exe
路径添加到系统 PATH
:
找到 cl.exe
的安装路径(根据 VS 版本和安装目录,示例路径):
cpp
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.常用命令选项
cpp
# 显示帮助
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++ 代码 + 示例到指定目录:
cpp
fastddsgen -d ./output -example C++ -topic HelloTopic HelloWorld.idl
效果:在 ./output
目录生成 HelloWorld
的结构体代码、类型注册代码,以及带 HelloTopic
主题的发布者 / 订阅者示例。
2.处理包含其他 IDL 的文件:
若 HelloWorld.idl
中用 #include "Common.idl"
引用了其他 IDL,需指定包含路径:
cpp
fastddsgen -I ./idl_include HelloWorld.idl
3.生成动态类型支持文件:
cpp
fastddsgen -typeobject -example C++ HelloWorld.idl
效果:除常规代码外,额外生成 HelloWorldTypeObjectSupport.hpp
和 .cxx
,支持动态类型发现。
4.6.复杂 IDL 示例
1.复杂数据类型 IDL
cpp
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.生成复杂类型
cpp
fastddsgen -replace -d generated -typeobject ComplexTypes.idl
4.7.在 CMake 项目中集成
1.基本的 CMakeLists.txt
cpp
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_FILES
HelloWorld.idl
ComplexTypes.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_publisher
src/publisher_main.cpp
${GENERATED_SOURCES}
)
add_executable(my_subscriber
src/subscriber_main.cpp
${GENERATED_SOURCES}
)
# 链接库
target_link_libraries(my_publisher
fastcdr
fastrtps
fastdds
)
target_link_libraries(my_subscriber
fastcdr
fastrtps
fastdds
)
2.高级 CMake 集成
cpp
# 自定义函数简化 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.项目结构
cpp
my_project/
├── CMakeLists.txt
├── idl/
│ ├── HelloWorld.idl
│ └── SensorData.idl
├── src/
│ ├── publisher.cpp
│ ├── subscriber.cpp
│ └── main.cpp
└── generated/ (自动生成)
2.构建脚本
cpp
#!/bin/bash
# build.sh
mkdir -p build
cd build
# 配置项目
cmake -DCMAKE_BUILD_TYPE=Release ..
# 编译
make -j$(nproc)
echo "构建完成!"
4.9.故障排除
1.fastddsgen 未找到
cpp
# 解决方案:检查安装路径
which fastddsgen
# 或者
find /usr -name "fastddsgen" 2>/dev/null
2.IDL 语法错误
cpp
# 验证 IDL 语法
fastddsgen -verbose MyTypes.idl
3.生成的代码编译错误
cpp
# 确保 Fast DDS 版本匹配
fastddsgen -version
pkg-config --modversion fastdds
4.IDL文件编码
IDL 文件一般都使用 UTF-8 编码
4.总结
fastddsgen
是 FastDDS 开发的 "必经之路",正确使用它可以大幅减少手动编写序列化和类型注册代码的工作量。实际开发中,建议结合 -example
参数生成示例代码,快速搭建通信框架。