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

 
 
> указатель на тип void, попытки создать общую функцию
andrvisht
сообщение Jan 3 2006, 13:06
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064



Всех с наступившим!!!
Решил написать функцию вывода строки в массив да так чтобы можно было эту строку брать как из SRAM так и из FLASH а поскольку указатели на FLASH и SRAM это разные вещи, то и типы указателей должны быть разные.
решил сделать тип void чтобы тип можно было задать при вызове функции с приведением типа.

вот код функции
Код
void LCDString(unsigned char StrNum, unsigned char StrPos, void *pStr)
{
  unsigned char i, c;
  i = StrPos;
  c = *((char*)pStr++);
  while ((i < SYM_STR-2) && (c != 0x00))
  {
    LCDStr[StrNum][i] = c;
    c = *((char*)pStr++);
    i++;
  }
}

прблема в том что компилятор не может сделать ++ для указателя типа void.
если создать отдельную переменную типа char *pS; то все нормально.

т.о. вопрос ? как сделать ++ указателю типа void без отдельной переменной, если возможно.

И еще вопрос. Если нужен передавать параметр типа bool
то можно как-то использовать
#if
#endif
т.е. напрмер
Код
strcpy(char *pStr, bool S_F)
{
#if S_F // если передан указатель на FLASH
flashcpy()
#else
Sramcpy()
#endif
}

или может так :
Код
strcpy(char *pStr)
{
#ifdef S_F
flashcpy()
#else
Sramcpy()
#endif
}
а вызов функции делать так

#define S_F
strcpy(*pStr)
#undef S_F

Есть еще вариант передавать два указателя, для Flash и SRAM и ненужный передавать 0
Или может еще каким образом поступают при такой задаче, просьба поделиться опытом ...
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
IgorKossak
сообщение Jan 3 2006, 14:15
Сообщение #2


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Всё, что Вы хотите легко реализуется перегружаемыми функциями в С++, а ещё элегантнее - шаблонной функцией.
Давно так делаю и очень доволен.
А если делать на С, то надо дополнительно передавать идентификатор типа и внутри универсальной функции делать приведение. Тогда и операция ++ будет работать.
Go to the top of the page
 
+Quote Post
andrvisht
сообщение Jan 3 2006, 14:26
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064



Цитата(IgorKossak @ Jan 3 2006, 18:15) *
Всё, что Вы хотите легко реализуется перегружаемыми функциями в С++, а ещё элегантнее - шаблонной функцией.
Давно так делаю и очень доволен.
А если делать на С, то надо дополнительно передавать идентификатор типа и внутри универсальной функции делать приведение. Тогда и операция ++ будет работать.

Попробовал sprintf() но сгенеренный код получился в 2 раза больше по времени выполнения.
это если я Вас правильно понял всмысле перегружаемых.
а что такое шаблонная функция ?
В С я новичок, поэтому может какие термины еще не знаю sad.gif
а разве
Код
(char*)pStr++;

Это не приведение типа ? вот на такой вариант компилятор говорит:
Error[Pe852]: expression must be a pointer to a complete object type

как правильно написать чтобы ++ работал?
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Jan 4 2006, 07:36
Сообщение #4


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(&-rey @ Jan 3 2006, 16:26) *
Попробовал sprintf() но сгенеренный код получился в 2 раза больше по времени выполнения.
это если я Вас правильно понял всмысле перегружаемых.

Наверное, всё-таки, не по времени выполнения, а по объёму, да и то при полном отсутствии оптимизации.
Почему-то никто не говорит (или я пропустил), что void* надо приводить не только к char*, но и к __flash char*. На это и указывает сообщение компилятора о незавершенном типе.
Основная ошибка в том, что в функции на момент исполнения нет информации о том, какого типа указатель был приведен к void*.
Решения было три:
- тип __generic;
- информация о типе указателя как аргумент в функции;
- два указателя.
Go to the top of the page
 
+Quote Post
andrvisht
сообщение Jan 4 2006, 07:51
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064



Цитата(IgorKossak @ Jan 4 2006, 11:36) *
Наверное, всё-таки, не по времени выполнения, а по объёму, да и то при полном отсутствии оптимизации.

возможно, я думал что она оптимизирована изначально, кроме того я сравнивал для варианта преобразования числа (перевода его в строку LCD)
Цитата
Почему-то никто не говорит (или я пропустил), что void* надо приводить не только к char*, но и к __flash char*. На это и указывает сообщение компилятора о незавершенном типе.

c этого момента пожалуйста поподробнее...
Цитата
Основная ошибка в том, что в функции на момент исполнения нет информации о том, какого типа указатель был приведен к void*.

но у меня ошибка была на этапе компиляции самой функции, а не в точке её вызова. Или это как-то взаимосвязвно ?
Цитата
Решения было три:
- тип __generic;
- информация о типе указателя как аргумент в функции;
- два указателя.

хотел применить 2-е но в результате остановился на 1-м.
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Jan 4 2006, 08:28
Сообщение #6


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(&-rey @ Jan 4 2006, 09:51) *
Цитата(IgorKossak @ Jan 4 2006, 11:36) *

Наверное, всё-таки, не по времени выполнения, а по объёму, да и то при полном отсутствии оптимизации.

возможно, я думал что она оптимизирована изначально, кроме того я сравнивал для варианта преобразования числа (перевода его в строку LCD)

??? Вообще-то Вы сами это либо задаёте либо нет в настройках проекта.
Цитата(&-rey @ Jan 4 2006, 09:51) *
Цитата

Почему-то никто не говорит (или я пропустил), что void* надо приводить не только к char*, но и к __flash char*. На это и указывает сообщение компилятора о незавершенном типе.

c этого момента пожалуйста поподробнее...
Цитата
Основная ошибка в том, что в функции на момент исполнения нет информации о том, какого типа указатель был приведен к void*.

но у меня ошибка была на этапе компиляции самой функции, а не в точке её вызова. Или это как-то взаимосвязвно ?

Ошибка у Вас стилистическая. А то, о чем сообщает компилятор, об этом Вам уже говорили. Повторюсь.
Вы писали
Цитата
(char*)pStr++;
Это означает, что pStr постоянно хранится в памяти или в регистрах в изначальном виде (типе). Временно приводится к типу char*, изымается по нему значение, он инкрементируется (если ещё инкрементируется), а в каком виде его теперь хранить (какого он типа?)?
В таком случае и нужен промежуточный указатель (не факт, что в результате он будет не тем же самым), который инициализируется единожды
Цитата
char*spStr = (char*)pStr;
и в дальнейшем только он и используется.
Цитата(&-rey @ Jan 4 2006, 09:51) *
Цитата

Решения было три:
- тип __generic;
- информация о типе указателя как аргумент в функции;
- два указателя.

хотел применить 2-е но в результате остановился на 1-м.

Насколько я помню тип __generic подразумевает также возможность указывания на __eeprom. Но даже и без этого Ваш код будет неприятно больше и работать будет заметно медленнее.
Go to the top of the page
 
+Quote Post
andrvisht
сообщение Jan 4 2006, 09:36
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064



Цитата(IgorKossak @ Jan 4 2006, 12:28) *
??? Вообще-то Вы сами это либо задаёте либо нет в настройках проекта.

Да конечно, возможно я не так выразился. Я имел предположение что поскольку функция библиотечная то она уже написана оптимально, а оптимизация в свойствах проекта влиять будет только на мой код. В принципе это можно проверить. так и сделаю.
Цитата
Ошибка у Вас стилистическая. А то, о чем сообщает компилятор, об этом Вам уже говорили......

да это я уже понял.
Цитата
Насколько я помню тип __generic подразумевает также возможность указывания на __eeprom. Но даже и без этого Ваш код будет неприятно больше и работать будет заметно медленнее.

ясно, это тоже проверю.
Go to the top of the page
 
+Quote Post
andrvisht
сообщение Jan 5 2006, 07:38
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064



Цитата
В принципе это можно проверить. так и сделаю.

Привожу данные после исследования скорости выполнения и размера *.bin файла (всего проекта) для 4 MHz m128.
сравнил вывод числа 65535 в массив при помощи sprintf(LCD,"%hu", 0xffff); (Normal DLIB)
и при помощи FloatToLCD(0,0,65535.0,0,1);
sprintf
без опт. разм. 6442 байт и 62008.5us с макс опт. разм. 6436 байт и 62008.25us
без опт. скор. 6442 байт и 62008.5us с макс опт. скор. 6436 байт и 62008.25us
FloatToLCD
без опт. разм. 2220 байт и 2315us с макс опт. разм. 2072 байт и 2287.75us
без опт. скор. 2252 байт и 2303us с макс опт. скор. 2116 байт и 2262.75us
Цитата
ясно, это тоже проверю.

Вариант с одним указателем типа __generic для вычитки из SRAM
без опт. разм. 2345 байт и 117.75us с макс опт. разм. 2073 байт и 92us
без опт. скорости 2351 байт и 96.5us с макс опт. скор. 2059 байт и 71.5us

Вариант с одним указателем типа __generic для вычитки из FLASH
без опт. разм. 2348 байт и 120.75us с макс опт. разм. 2080 байт и 94.75us
без опт. скор. 2354 байт и 99.5us с макс опт. скор. 2060 байт и 74.25us

Вариант с двумя указателями для SRAM и FLASH и равенстве нулю FLASH.
без опт. разм. 2353 байт и 115us с макс опт. разм. 2067 байт и 115.75us
без опт. скор. 2373 байт и 92us с макс опт. скор. 2073 байт и 74.25us

Вариант с двумя указателями для SRAM и FLASH и равенстве нулю SRAM.
без опт. разм. 2354 байт и 125.5us с макс опт. разм. 2068 байт и 118.5us
без опт. скор. 2374 байт и 102.5us с макс опт. скор. 2074 байт и 82.5us

Комментировать не буду, дабы не быть уличенным в пропаганде smile.gif
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- &-rey   указатель на тип void   Jan 3 2006, 13:06
|- - prottoss   Цитата(&-rey @ Jan 3 2006, 21:26...   Jan 3 2006, 15:38
||- - &-rey   Цитата(prottoss @ Jan 3 2006, 19:38) В Си...   Jan 3 2006, 15:50
|||- - prottoss   [quote name='&-rey' date='Jan 3 20...   Jan 3 2006, 16:17
|||- - SSerge   Цитата(&-rey @ Jan 3 2006, 21:50...   Jan 3 2006, 18:04
||- - defunct   Цитата(prottoss @ Jan 3 2006, 17:38) Вы с...   Jan 7 2006, 13:30
||- - prottoss   Цитата(defunct @ Jan 7 2006, 20:30) Цитат...   Jan 7 2006, 21:17
||- - defunct   Цитата(prottoss @ Jan 7 2006, 23:17) Цита...   Jan 9 2006, 15:36
||- - prottoss   Цитата(defunct @ Jan 9 2006, 22:36) ...   Jan 9 2006, 19:29
||- - defunct   Цитата(prottoss @ Jan 9 2006, 21:29) а Вы...   Jan 9 2006, 20:01
|- - Old1   To &-rey. Я тут для себя тоже провел кое-каки...   Jan 7 2006, 20:51
- - _artem_   sdelay tak : c = *(((char*)pStr)++); po moem...   Jan 3 2006, 15:58
|- - &-rey   Цитата(_artem_ @ Jan 3 2006, 19:58) sdela...   Jan 3 2006, 16:09
- - SSerge   Цитата(&-rey @ Jan 3 2006, 19:06...   Jan 3 2006, 16:12
|- - &-rey   Цитата(SSerge @ Jan 3 2006, 20:12) А комп...   Jan 3 2006, 16:27
|- - SSerge   Цитата(&-rey @ Jan 3 2006, 22:27...   Jan 3 2006, 17:08
|- - &-rey   Цитата(SSerge @ Jan 3 2006, 21:08) Код c...   Jan 4 2006, 07:38
- - _artem_   OK, v principe kompayler prav )), on ne mozet preo...   Jan 3 2006, 16:27
- - ObitJr   Я думаю неправильно говорить компилятор незнает ил...   Jan 10 2006, 19:17
|- - prottoss   Цитата(ObitJr @ Jan 11 2006, 02:17) Я дум...   Jan 10 2006, 19:57
- - sensor_ua   указатель void, ИМХО, действительно не может знать...   Jan 10 2006, 20:27
- - ObitJr   1. Если что-то кажется, я конечно извеняюсь, есть...   Jan 10 2006, 21:33
|- - dxp   Цитата(ObitJr @ Jan 11 2006, 03:33) 1. Ес...   Jan 11 2006, 07:19
|- - &-rey   to Old1: Спасибо, просмотрел Ваши функции, узнал д...   Jan 11 2006, 07:55
|- - ObitJr   Ищем книгу "The New C Standard - An economic ...   Jan 11 2006, 09:02
|- - Old1   To &-rey. ЦитатаА вот если в функции с __gener...   Jan 12 2006, 09:57
|- - &-rey   to Old1: Спасибо за ссылку, мои подозрения оправда...   Jan 12 2006, 11:49
|- - Old1   Цитата(Old1 @ Jan 12 2006, 13:57) ...если...   Jan 13 2006, 09:58
- - _artem_   esli vse taki xotite manipulirovat void v funkcii ...   Jan 11 2006, 16:22
- - &-rey   Цитата(_artem_ @ Jan 11 2006, 20:22) esli...   Jan 11 2006, 16:38


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

 


RSS Текстовая версия Сейчас: 23rd June 2025 - 05:05
Рейтинг@Mail.ru


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