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

C++无需调用函数获取本地静态错误信息的替代方案(TouchGFX模拟器)

问题描述

我需要在不同文件的C++代码中,于setError函数调用下方添加如下形式的错误信息:

{
    setError(1); // 1将被唯一常量(枚举值)替换
    #ifdef SIMULATOR
    ADD_INFO_FOR_ERROR(1, "some explanation for error 1");
    #endif
}

该信息仅在定义SIMULATOR宏时生效,无需调用对应本地函数,就能在main()中获取这些信息并导出为表格。

原本我通过GCC的段属性实现该需求,定义如下宏:

#define ADD_INFO_FOR_ERROR(INTEGERVALUE, CONSTANTTEXT) \
    static const struct { \
        int index; \
        const char *text; \
    } entry_##INTEGERVALUE __attribute__((section(".my_table_section"), used)) = {INTEGERVALUE, CONSTANTTEXT};

但该方案在TouchGFX模拟器中无法正常获取信息(嵌入式生产系统可正常运行)。我使用GCC编译器,请问是否有可行的替代方案或工具?

替代方案

方案1:C++全局对象自动注册

借助标准C++全局对象的构造特性实现注册逻辑,不依赖编译器段属性:

首先定义全局注册表和注册器结构:

#include <vector>
#include <utility>

#ifdef SIMULATOR
// 全局错误信息注册表
static std::vector<std::pair<int, const char*>> error_info_registry;

// 注册器对象,构造时自动将错误信息加入注册表
struct ErrorInfoRegistrar {
    ErrorInfoRegistrar(int code, const char* msg) {
        error_info_registry.emplace_back(code, msg);
    }
};

// 替换原宏,用静态注册器对象实现自动注册
#define ADD_INFO_FOR_ERROR(CODE, MSG) \
    static ErrorInfoRegistrar error_reg_##CODE(CODE, MSG);
#else
// 非SIMULATOR环境下宏为空
#define ADD_INFO_FOR_ERROR(CODE, MSG)
#endif

使用时直接在setError下方插入ADD_INFO_FOR_ERROR(1, "some explanation for error 1")即可。程序启动后,所有注册的错误信息都会存入error_info_registry,在main()中遍历该容器就能导出表格。

优势:完全符合C++标准,跨平台兼容性强,TouchGFX模拟器环境可正常工作。

方案2:GCC构造函数属性实现C风格注册

利用GCC的__attribute__((constructor))扩展,让注册函数在main执行前自动运行:

#ifdef SIMULATOR
#include <stdlib.h>

// 错误信息存储表格
#define MAX_ERROR_ENTRIES 100
static struct {
    int code;
    const char* msg;
} error_table[MAX_ERROR_ENTRIES];
static int error_count = 0;

// 注册错误信息的函数
static void register_error(int code, const char* msg) {
    if (error_count < MAX_ERROR_ENTRIES) {
        error_table[error_count++] = {code, msg};
    }
}

// 宏定义:生成带constructor属性的静态注册函数
#define ADD_INFO_FOR_ERROR(CODE, MSG) \
    static void reg_error_##CODE(void) __attribute__((constructor)); \
    static void reg_error_##CODE(void) { \
        register_error(CODE, MSG); \
    }
#else
#define ADD_INFO_FOR_ERROR(CODE, MSG)
#endif

每个ADD_INFO_FOR_ERROR会生成一个自动执行的注册函数,将错误信息写入全局表格,main()中直接读取error_table和error_count即可。

注意:__attribute__((constructor))是GCC扩展,TouchGFX模拟器基于桌面GCC编译,兼容性有保障。

方案3:预处理器扫描生成静态注册表

通过脚本扫描源代码中的宏调用,编译前生成包含所有错误信息的静态文件:

  1. 先定义用于标记的空宏:
#ifdef SIMULATOR
#define ADD_INFO_FOR_ERROR(CODE, MSG) ERROR_ENTRY(CODE, MSG)
#else
#define ADD_INFO_FOR_ERROR(CODE, MSG)
#endif
  1. 编写脚本(如Python)遍历所有.cpp文件,提取ERROR_ENTRY的参数,自动生成error_info_auto_gen.cpp:
#include "error_info.h"

// 自动生成的错误信息数组
const ErrorEntry error_entries[] = {
    {1, "some explanation for error 1"},
    {2, "some explanation for error 2"},
    // 所有扫描到的错误条目
};
const size_t error_entry_count = sizeof(error_entries)/sizeof(error_entries[0]);
  1. 在main()中直接使用生成的error_entries数组导出表格。

优势:运行时无额外初始化逻辑,所有错误信息编译时固定,适合对启动流程有严格要求的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 03:33:18