реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Перенос кода в среду IAR
Василий Зыков
сообщение Mar 14 2017, 09:45
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 63
Регистрация: 11-11-06
Из: Екатеринбург
Пользователь №: 22 191



Добрый день, коллеги!
Переношу проект, написанный в AVR Studio 4 под WinAvr, в среду IAR
Столкнулся с тем, что IAR ругается на такую конструкцию (ошибка Pe513):

ssp.spiHwInit=(void *)atmega_spi_init;

где объявления даны следующим образом:

euint8 atmega_spi_init(atmegaSpiInterface *iface);

и
Код
struct SdSpiProtocol
{
    void *spiHwInterface;
    euint8 (*spiHwInit)(void* spiHwInterface);
    euint8 (*spiSendByte)(void* spiHwInterface,euint8 data);
};
typedef struct SdSpiProtocol SdSpiProtocol;
Подскажите, пожалуйста, как ее правильно описать в IAR?

Сообщение отредактировал IgorKossak - Mar 14 2017, 15:08
Причина редактирования: [codebox] для длинного кода. [code]-для короткого!!! Лишние пустые строки!
Go to the top of the page
 
+Quote Post
scifi
сообщение Mar 14 2017, 09:46
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Очевидно, компилируете в режиме Си++. Не надо так делать. Пусть будет просто тёплый ламповый Си.
Go to the top of the page
 
+Quote Post
Василий Зыков
сообщение Mar 14 2017, 09:53
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 63
Регистрация: 11-11-06
Из: Екатеринбург
Пользователь №: 22 191



Цитата(scifi @ Mar 14 2017, 14:46) *
Очевидно, компилируете в режиме Си++. Не надо так делать. Пусть будет просто тёплый ламповый Си.

Да нет, проверил, в настройках стоит С. C dialect C99
Go to the top of the page
 
+Quote Post
scifi
сообщение Mar 14 2017, 10:10
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Василий Зыков @ Mar 14 2017, 12:53) *
Да нет, проверил, в настройках стоит С. C dialect C99

А, не заметил, что, очевидно, указатель на функцию приводите к void* и присваиваете другому указателю на функцию. Это безобразие. Если какой-то компилятор такое проглатывал, то это неправильный компилятор.
Можно сделать вот так:
Код
ssp.spiHwInit=(euint8 (*)(void*))atmega_spi_init;

Но необходимость приведения типа указателя на функцию настораживает, конечно. Кто придумал всё это безобразие?
Go to the top of the page
 
+Quote Post
Василий Зыков
сообщение Mar 14 2017, 10:55
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 63
Регистрация: 11-11-06
Из: Екатеринбург
Пользователь №: 22 191



Цитата(scifi @ Mar 14 2017, 15:10) *
А, не заметил, что, очевидно, указатель на функцию приводите к void* и присваиваете другому указателю на функцию. Это безобразие. Если какой-то компилятор такое проглатывал, то это неправильный компилятор.
Можно сделать вот так:
Код
ssp.spiHwInit=(euint8 (*)(void*))atmega_spi_init;

Но необходимость приведения типа указателя на функцию настораживает, конечно. Кто придумал всё это безобразие?


Winavr такое проглатывает..... другой разработчик давно написал этот код. Работало и работало. Пока не появилась необходимость что-то поменять.

Спасибо огромное! Заработало! Только... теперь я не понимаю, как эта конструкция построена. Так сложно на первый взгляд. Спасибо еще раз!
Почему-то без приведения типа компилятор тоже выдает ошибку... меня это тоже смущает.

Сообщение отредактировал IgorKossak - Mar 14 2017, 15:09
Причина редактирования: бездумное цитирование
Go to the top of the page
 
+Quote Post
scifi
сообщение Mar 14 2017, 11:35
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Василий Зыков @ Mar 14 2017, 13:55) *
теперь я не понимаю, как эта конструкция построена. Так сложно на первый взгляд.

Приведение к типу "указатель на функцию". Ну да, с непривычки странно выглядит.

Цитата(Василий Зыков @ Mar 14 2017, 13:55) *
Почему-то без приведения типа компилятор тоже выдает ошибку... меня это тоже смущает.

Надо смотреть, какой тип у ssp.spiHwInit. Очевидно, какой-то другой, раз компилятор жалуется без приведения типа.
Go to the top of the page
 
+Quote Post
SSerge
сообщение Mar 14 2017, 13:51
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528



Цитата(scifi @ Mar 14 2017, 18:35) *
Надо смотреть, какой тип у ssp.spiHwInit. Очевидно, какой-то другой, раз компилятор жалуется без приведения типа.

Так в первом сообщении всё есть.
Поле в структуре описано как указатель на функцию, принимающую указатель на void и возвращающую euint8,
а ему пытаются присвоить указатель на функцию, принимающую указатель на atmegaSpiInterface и возвращающую euint8.
Ясное дело, без явного преобразования типа такое делать нельзя, и преобразование к типу void* не поможет.
Вот если наоборот - полю типа void* можно присваивать любой указатель. Но тогда для вызова функции по такому указателю потребуется преобразование его типа в тип, соответствующий вызываемой функции, что открывает массу возможностей для ошибок.

Вообще, передача в функции указателей на структуры и наличие в структурах указателей на функции верный признак того, что рамки С коду уже тесны и пора переходить на С++, а не заниматься имитацией на С классов и виртуальных функций.


--------------------
Russia est omnis divisa in partes octo.
Go to the top of the page
 
+Quote Post
aiwa
сообщение Mar 14 2017, 13:52
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Цитата(Василий Зыков @ Mar 14 2017, 12:55) *
Только... теперь я не понимаю, как эта конструкция построена. Так сложно на первый взгляд.


Более наглядная конструкция:
*((void**)&ssp.spiHwInit) = (void*)atmega_spi_init;

Go to the top of the page
 
+Quote Post
scifi
сообщение Mar 14 2017, 14:05
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(aiwa @ Mar 14 2017, 16:52) *
Более наглядная конструкция:
*((void**)&ssp.spiHwInit) = (void*)atmega_spi_init;

Так это же совсем другая семантика. Не будет работать, короче.
Go to the top of the page
 
+Quote Post
aiwa
сообщение Mar 14 2017, 15:29
Сообщение #10


Местный
***

Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Цитата(scifi @ Mar 14 2017, 16:05) *
Так это же совсем другая семантика. Не будет работать, короче.

Зависит от модели памяти: требуется совпадение физических размеров "DATA pointer" и "FUNC pointer", тогда будет работать.
Но пример приведен как альтернатива для понимания.
Правильно будет использовать Ваш вариант приведения.
Go to the top of the page
 
+Quote Post
scifi
сообщение Mar 14 2017, 19:46
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(aiwa @ Mar 14 2017, 18:29) *
Но пример приведен как альтернатива для понимания.

Что-то я в звёздочках запутался. Вроде бы должно и эдак получиться laughing.gif
Go to the top of the page
 
+Quote Post
Василий Зыков
сообщение Mar 15 2017, 05:52
Сообщение #12


Участник
*

Группа: Участник
Сообщений: 63
Регистрация: 11-11-06
Из: Екатеринбург
Пользователь №: 22 191



Спасибо большое вам за комментарии и разъяснения!

Цитата(aiwa @ Mar 14 2017, 18:52) *
Более наглядная конструкция:
*((void**)&ssp.spiHwInit) = (void*)atmega_spi_init;


Нет, пожалуй, первая конструкция мне понятнее sm.gif
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 5th July 2025 - 06:00
Рейтинг@Mail.ru


Страница сгенерированна за 0.01449 секунд с 7
ELECTRONIX ©2004-2016