Я потратил часы / дни на это. Мне нужна помощь.
Оригинальный код в C. Один конкретный бит загружает значение из памяти и сохраняет его;
char *s = NULL;
if (sysparam_get_string("anim1_name", &s) == SYSPARAM_OK) {
homekit_value_destruct(&anim1_name.value);
anim1_name.value = HOMEKIT_STRING(s);
}
Однако я переношу это на Arduino, и метод сохранения / загрузки параметров выполняется в C ++. Поэтому я вызываю следующее в своем коде C ++:
extern "C" {
void sysparam_load_string(char* param_name, const char* value);
}
String s;
s = preferences.getString("anim1_name");
sysparam_load_string("anim1_name", s.c_str());
И затем в коде C, который у меня есть;
void sysparam_load_string(char *param_name, const char *value) {
homekit_value_destruct(&anim1_name.value);
anim1_name.value = HOMEKIT_STRING(value);
}
Это приводит к мусору.
Если я попытаюсь сделать это
sysparam_load_string("anim1_name", "Jack");
Это работает. «Джек» появляется. НО, если я пытаюсь изменить имя, программа падает, говоря, что целевой указатель находится вне кучи (возможно, потому что я пытаюсь использовать указатель, который является постоянным?)
Может кто-то помочь объяснить, как выполнить это должным образом / безопасно? Я не уверен, связано ли это с «Временными объектами», или с проблемами констант, или с областью действия ... Я ненавижу строки ...
FYI; макрос HOMEKIT_STRING:
#define HOMEKIT_STRING_(value, ...) \
{.format=homekit_format_string, .string_value=(value), ##__VA_ARGS__}
#define HOMEKIT_STRING(value, ...) (homekit_value_t) HOMEKIT_STRING_(value, ##__VA_ARGS__)
И struct
-
typedef struct {
bool is_null : 1;
bool is_static : 1;
homekit_format_t format : 6;
union {
bool bool_value;
int int_value;
uint8_t uint8_value;
uint16_t uint16_value;
uint32_t uint32_value;
uint64_t uint64_value;
float float_value;
char *string_value;
tlv_values_t *tlv_values;
struct {
uint8_t *data_value;
size_t data_size;
};
};
} homekit_value_t;