You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ESP-IDF v4.4 C++项目调用BLE_UUID16_DECLARE宏编译报错问题

ESP-IDF C++环境下BLE_UUID16_DECLARE宏编译报错解决办法

根本原因

NimBLE蓝牙栈提供的BLE_UUID16_DECLARE、BLE_UUID16_INIT系列宏,底层使用了C语言特有的复合字面量语法,该语法不被C++标准支持:

  • C语言中复合字面量是左值,可以取地址直接用于全局/静态变量初始化、结构体指定初始化
  • C中复合字面量是右值,不允许取地址做长期指针赋值,也不允许在静态初始化场景使用
    这就是为什么纯C项目代码正常,切换到.cpp编译就会出现"expected a ')'""expected declaration before '}' token"这类语法报错,报错指向官方头文件是因为宏展开后C
    语法解析失败。

解决方案

方案1:拆分BLE配置代码为纯C文件(最推荐,无侵入)

将用到NimBLE宏的UUID定义、GATT服务/特征表代码单独抽为纯C文件编译,头文件用extern "C"包裹后供C++代码调用,完全不需要修改原有逻辑:

  1. 新增ble_config.c(纯C编译):
#include <stdio.h>
#include "host/ble_uuid.h"
#include "services/gatt/ble_gatt.h"

#define DEV_INFO 0x180A
#define MANUFACTURER 0x2A29

const ble_uuid_t* devInfoUuid = BLE_UUID16_DECLARE(DEV_INFO);
const ble_uuid_t* manufacturerUuid = BLE_UUID16_DECLARE(MANUFACTURER);

static int device_info(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) {
    os_mbuf_append(ctxt->om, "Achieved", strlen("Achieved"));
    return 0;
}

const struct ble_gatt_chr_def gatt_chrs[] = {
    {
        .uuid = manufacturerUuid,
        .access_cb = device_info,
        .flags = BLE_GATT_CHR_F_READ
    },
    {0}
};

const struct ble_gatt_svc_def gat_svcs[] = {
    {
        .type = BLE_GATT_SVC_TYPE_PRIMARY,
        .uuid = devInfoUuid,
        .characteristics = gatt_chrs
    },
    {0}
};
  1. 新增ble_config.h:
#ifndef BLE_CONFIG_H
#define BLE_CONFIG_H

#ifdef __cplusplus
extern "C" {
#endif

#include "host/ble_uuid.h"
#include "services/gatt/ble_gatt.h"

extern const ble_uuid_t* devInfoUuid;
extern const ble_uuid_t* manufacturerUuid;
extern const struct ble_gatt_svc_def gat_svcs[];

#ifdef __cplusplus
}
#endif

#endif
  1. 原有C++文件直接includeble_config.h即可使用定义好的UUID、GATT服务表。

方案2:C++代码中手动构造UUID(无需拆分文件)

如果不想拆分文件,可以直接在C++代码中按照UUID结构体的定义手动初始化,不使用官方宏即可:

#include "host/ble_uuid.h"

#define DEV_INFO 0x180A
#define MANUFACTURER 0x2A29

// 手动构造16位UUID,完全符合C++语法
const ble_uuid16_t dev_info_uuid = {
    .u = { .type = BLE_UUID_TYPE_16 },
    .value = DEV_INFO
};
const ble_uuid_t* devInfoUuid = (const ble_uuid_t*)&dev_info_uuid;

const ble_uuid16_t manu_uuid = {
    .u = { .type = BLE_UUID_TYPE_16 },
    .value = MANUFACTURER
};
const ble_uuid_t* manufacturerUuid = (const ble_uuid_t*)&manu_uuid;

内容的提问来源于stack exchange,提问作者kyrpav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 22:45:07