目录

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: 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++/Pythonfastddsgen -example C++ HelloWorld.idl
-topic <名称>为示例代码指定 Topic 名称(默认用 IDL 结构体名)fastddsgen -example C++ -topic MyTopic HelloWorld.idl
-I <路径>添加 IDL 包含文件的搜索路径(类似 C++ 的 -Ifastddsgen -I ./include Common.idl
-D <宏定义>定义预处理宏(类似 C++ 的 -Dfastddsgen -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 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_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 集成

# 自定义函数简化 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.sh
mkdir -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 参数生成示例代码,快速搭建通信框架。

posted on 2025-10-02 22:57  ycfenxi  阅读(24)  评论(0)    收藏  举报