|
указатель на тип void, попытки создать общую функцию |
|
|
|
Jan 3 2006, 13:06
|
Местный
  
Группа: Свой
Сообщений: 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 Или может еще каким образом поступают при такой задаче, просьба поделиться опытом ...
|
|
|
|
|
 |
Ответов
|
Jan 3 2006, 14:26
|
Местный
  
Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064

|
Цитата(IgorKossak @ Jan 3 2006, 18:15)  Всё, что Вы хотите легко реализуется перегружаемыми функциями в С++, а ещё элегантнее - шаблонной функцией. Давно так делаю и очень доволен. А если делать на С, то надо дополнительно передавать идентификатор типа и внутри универсальной функции делать приведение. Тогда и операция ++ будет работать. Попробовал sprintf() но сгенеренный код получился в 2 раза больше по времени выполнения. это если я Вас правильно понял всмысле перегружаемых. а что такое шаблонная функция ? В С я новичок, поэтому может какие термины еще не знаю  а разве Код (char*)pStr++; Это не приведение типа ? вот на такой вариант компилятор говорит: Error[Pe852]: expression must be a pointer to a complete object type как правильно написать чтобы ++ работал?
|
|
|
|
|
Jan 4 2006, 07:36
|

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

|
Цитата(&-rey @ Jan 3 2006, 16:26)  Попробовал sprintf() но сгенеренный код получился в 2 раза больше по времени выполнения. это если я Вас правильно понял всмысле перегружаемых. Наверное, всё-таки, не по времени выполнения, а по объёму, да и то при полном отсутствии оптимизации. Почему-то никто не говорит (или я пропустил), что void* надо приводить не только к char*, но и к __flash char*. На это и указывает сообщение компилятора о незавершенном типе. Основная ошибка в том, что в функции на момент исполнения нет информации о том, какого типа указатель был приведен к void*. Решения было три: - тип __generic; - информация о типе указателя как аргумент в функции; - два указателя.
|
|
|
|
|
Jan 4 2006, 07:51
|
Местный
  
Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064

|
Цитата(IgorKossak @ Jan 4 2006, 11:36)  Наверное, всё-таки, не по времени выполнения, а по объёму, да и то при полном отсутствии оптимизации. возможно, я думал что она оптимизирована изначально, кроме того я сравнивал для варианта преобразования числа (перевода его в строку LCD) Цитата Почему-то никто не говорит (или я пропустил), что void* надо приводить не только к char*, но и к __flash char*. На это и указывает сообщение компилятора о незавершенном типе. c этого момента пожалуйста поподробнее... Цитата Основная ошибка в том, что в функции на момент исполнения нет информации о том, какого типа указатель был приведен к void*. но у меня ошибка была на этапе компиляции самой функции, а не в точке её вызова. Или это как-то взаимосвязвно ? Цитата Решения было три: - тип __generic; - информация о типе указателя как аргумент в функции; - два указателя. хотел применить 2-е но в результате остановился на 1-м.
|
|
|
|
|
Jan 4 2006, 08:28
|

Шаман
     
Группа: Модераторы
Сообщений: 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. Но даже и без этого Ваш код будет неприятно больше и работать будет заметно медленнее.
|
|
|
|
|
Jan 4 2006, 09:36
|
Местный
  
Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064

|
Цитата(IgorKossak @ Jan 4 2006, 12:28)  ??? Вообще-то Вы сами это либо задаёте либо нет в настройках проекта. Да конечно, возможно я не так выразился. Я имел предположение что поскольку функция библиотечная то она уже написана оптимально, а оптимизация в свойствах проекта влиять будет только на мой код. В принципе это можно проверить. так и сделаю. Цитата Ошибка у Вас стилистическая. А то, о чем сообщает компилятор, об этом Вам уже говорили...... да это я уже понял. Цитата Насколько я помню тип __generic подразумевает также возможность указывания на __eeprom. Но даже и без этого Ваш код будет неприятно больше и работать будет заметно медленнее. ясно, это тоже проверю.
|
|
|
|
|
Jan 5 2006, 07:38
|
Местный
  
Группа: Свой
Сообщений: 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 Комментировать не буду, дабы не быть уличенным в пропаганде
|
|
|
|
Сообщений в этой теме
&-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
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|