Перейти к содержанию
    

Есть struct:

typedef struct command
{
    char *name;  //command name
    char mode;   //0-read, 1- read/write 
    int minval;  
    int maxval;  
    void (*fp) (int com_num);  //pointer to function
    void *vp;   //pointer to variable
}command;

command commands[] = {
    {"imax1", 1, 0, 10000, GetSetImax, &max_current1},
    {"imax2", 1, 0, 10000, GetSetImax, &max_current2},
};

Я могу считать переменную

UsartSendInt( (int)commands[com_num].vp );

Но записать не получается

(int *)(commands[com_num].vp) = mux_cur;

Что я делаю не так?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как вам такой вариант:

commands[com_num].vp = (void *)&mux_cur;

компайлер не ругается но я что то не понимаю - мы приводим к войд?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

но я что то не понимаю - мы приводим к войд?

Да, раз у вас в структуре хранится void *, то и приводите к void *. Потом обратно можно получить указатель на что угодно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

попробуйте *(int *)... = val

вроде работет. спасибо.

 

Да, раз у вас в структуре хранится void *, то и приводите к void *. Потом обратно можно получить указатель на что угодно.

все рвно не понимаю - как он запишет инеджер в войд?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

все рвно не понимаю - как он запишет инеджер в войд?

Во-первых, он запишет указатель на интеджер в указатель на войд. Так делают, чтобы использовать одну структуру для разных данных (полиморфизм).

Во-вторых, это вам надо выяснить, зачем вы в своей же структуре храните переменную как указатель на войд. Храните саму переменную как инт и всё будет проще.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

все рвно не понимаю - как он запишет инеджер в войд?

 

int*, char*, short*, void* и вообще любой указатель - это просто число. Адрес переменной. int или char определяют сколько байт нужно считать при обращении к переменной. А void* получается пустой указатель. т.е. указатель на переменную без привязки к её типу (разрядности). Чтоб корректно считать данные при чтении вы должны привести его к одному из существующих типов - int*, char* и т.д.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Во-первых, он запишет указатель на интеджер в указатель на войд. Так делают, чтобы использовать одну структуру для разных данных (полиморфизм).

Во-вторых, это вам надо выяснить, зачем вы в своей же структуре храните переменную как указатель на войд. Храните саму переменную как инт и всё будет проще.

у меня переменная может быть разной размерности - поэтому указатель на войд, чтоб потом привести к нужному типу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

у меня переменная может быть разной размерности

В таком случае, если будете писать

*(int *)... = val

рискуете получить падающую программу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В таком случае, если будете писать

*(int *)... = val

рискуете получить падающую программу.

ну если переменная скажем чар то я привожу к *(char *). по моему вполне безопасно.

Изменено пользователем Jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В таком случае, если будете писать

*(int *)... = val

рискуете получить падающую программу.

Поэтому нужно писать *(мой_сегодняшний_тип *)... = val

А выше #typedef мой_сегодняшний_тип int.

Компилятору не дается шанса найти ошибку и предупредить.

Упасть может и в случае, если хранить указатель на int, но забыть его проинициализировать.

И если ТС не подтянет знания по указателям, то и в многих других местах (заканчивая изощренными, типа, невыровненные данные).

 

С другой стороны, указатель как правило 32-битный.

Храните int и забудте о char, short.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поэтому нужно писать *(мой_сегодняшний_тип *)... = val

А выше #typedef мой_сегодняшний_тип int.

Компилятору не дается шанса найти ошибку и предупредить.

Упасть может и в случае, если хранить указатель на int, но забыть его проинициализировать.

И если ТС не подтянет знания по указателям, то и в многих других местах (заканчивая изощренными, типа, невыровненные данные).

 

С другой стороны, указатель как правило 32-битный.

Храните int и забудте о char, short.

 

то есть лучше писать * (uint32_t *) ?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

С другой стороны, указатель как правило 32-битный.

Храните int и забудте о char, short.

по моему это лучший способ избежать головной боли. :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...