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

如何在C语言中实现C++模板式的通用EEPROM读写函数?

如何在C语言中实现通用的EEPROM读写函数?

我在C++里用模板轻松实现了支持任意类型的EEPROM读写通用函数:

template<class T> int EEPROM_put(int ee, const T& value) {
const byte* p = (const byte*)(const void*)&value;
unsigned int i;

for (i = 0; i < sizeof(value); i++) foo(ee++, *p++);
return i;
 }

template<class T> int EEPROM_get(int ee, T& value) {
byte* p = (byte*)(void*)&value;
unsigned int i;

for (i = 0; i < sizeof(value); i++) *p++ = foo(ee++);
return i;
}

但自己写的C语言版本只能支持u16类型,而且EEPROM_get函数还没法正常工作:

int EEPROM_put(int ee, u16 value){
    const u8* p = (const u8*)(const void*)&value;
    unsigned int i;

    for (i = 0; i < sizeof(value); i++) {
        eeprom_write_1byte(ee++, *p++); Delay_Ms(10);
    }
    return i;
}

int EEPROM_get(int ee,  u16 value) {
  u8* p = (u8*)(void*)&value;
  unsigned int i;

  for (i = 0; i < sizeof(value); i++) {
      *p++ = eeprom_read_1byte(ee++); Delay_Ms(10);
  }
  return i;
}

想问下有没有办法在C语言里实现和C++模板等效的通用EEPROM读写函数?


解决方案

C语言没有模板特性,但可以通过void指针+传递类型大小实现通用化,先修复你现有EEPROM_get的问题,再逐步实现通用版本:

1. 修复u16版本的EEPROM_get

你的EEPROM_get参数是传值,修改的只是函数内部的副本,外部变量完全不会更新。必须改成传指针:

int EEPROM_get_u16(int ee, u16 *value) {
  u8* p = (u8*)(void*)value;
  unsigned int i;

  for (i = 0; i < sizeof(*value); i++) {
      *p++ = eeprom_read_1byte(ee++); Delay_Ms(10);
  }
  return i;
}

调用时要传变量地址:EEPROM_get_u16(0x00, &my_u16_var);

2. 实现通用读写函数

利用C语言void*可指向任意类型的特性,搭配字节大小参数,就能写出支持所有类型的通用函数:

通用写函数

int EEPROM_put_generic(int ee, const void *value, size_t size) {
    const u8* p = (const u8*)value;
    unsigned int i;

    for (i = 0; i < size; i++) {
        eeprom_write_1byte(ee++, *p++);
        Delay_Ms(10);
    }
    return i;
}

调用示例:

// 写入u16类型
u16 num = 0x1234;
EEPROM_put_generic(0x00, &num, sizeof(num));

// 写入结构体类型
typedef struct {
    float temp;
    u8 status;
} SensorData;
SensorData data = {25.5, 0x01};
EEPROM_put_generic(0x02, &data, sizeof(data));

通用读函数

int EEPROM_get_generic(int ee, void *value, size_t size) {
    u8* p = (u8*)value;
    unsigned int i;

    for (i = 0; i < size; i++) {
        *p++ = eeprom_read_1byte(ee++);
        Delay_Ms(10);
    }
    return i;
}

调用示例:

// 读取u16类型
u16 read_num;
EEPROM_get_generic(0x00, &read_num, sizeof(read_num));

// 读取结构体类型
SensorData read_data;
EEPROM_get_generic(0x02, &read_data, sizeof(read_data));

3. 进阶:用宏简化调用

每次手动写sizeof略显繁琐,可以用宏封装,让调用体验接近C++模板:

#define EEPROM_PUT(ee, value) EEPROM_put_generic((ee), &(value), sizeof(value))
#define EEPROM_GET(ee, value) EEPROM_get_generic((ee), &(value), sizeof(value))

调用变得非常简洁:

u16 num = 0x1234;
EEPROM_PUT(0x00, num);

u16 read_num;
EEPROM_GET(0x00, read_num);

SensorData data = {25.5, 0x01};
EEPROM_PUT(0x02, data);

SensorData read_data;
EEPROM_GET(0x02, read_data);

注意事项

  • 确保传递给函数的指针有效,避免空指针或野指针
  • 对于结构体等复杂类型,要注意字节序和内存对齐问题,不同编译器或平台可能有差异,跨平台场景建议手动处理内存布局
  • Delay_Ms(10)需根据EEPROM型号调整,确保写入完成再执行下一次操作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 18:42:24