printf LCD... и вопрос и ответ

Тема в разделе "Флудилка", создана пользователем Igor68, 17 ноя 2019.

  1. Igor68

    Igor68 Гуру

    Это флуд в ответе? Ведь чЁтко указал (даже пример указал):
    Код (C++):
    int func1(char * a, ...)
    {
       char * buf;
       func2(buf, a, ...);
      return 0;
    }
    Что надо сделать функцию с переменным количеством элементов, которые будут переданы в применяемой другой функции, вызываемой из этой функции. Вот думаю: сколько запятых и точек надо поставить что бы LCD_Printf воспринимали за функцию, которую надо сделать... именно из этой функции и надо вызвать стандарную sprintf при этом передав ей всё это переменное количество входных параметров.
    Даже и подумать не мог, что одно и тоже говорить обязательно. Сейчас (выше в самом начале) обрабатываю весь список параметров и вызываю много раз sprintf. А вопрос не изменён... он выше.
    Тут и сразу и вопрос другой: "Может это не реально?" Сам я не знаю как именно это сделать.
     
  2. Это типа вы так тролите??? Передаете список аргументов из стека как ...
    Или это не дописанный код?

    П.С.
    Думал как-то пример hello world запостить, но постеснялся, а сейчас думаю зря ;)

    П.П.С.
    Если хоть раз приходилось пользоваться функцией printf из stdio.h то наверняка заметили, что кроме этой функции есть целое семейство с различными префиксами и сигнатурами.
    В том числе не только с переменным числом аргументов, но и с передачей списка аргументов через va_list
    Код (Text):
    ~$ man 3 printf

    PRINTF(3)  Linux Programmer's Manual  PRINTF(3)

    NAME
      printf, fprintf, dprintf, sprintf, snprintf, vprintf, vfprintf, vdprintf, vsprintf, vsnprintf - formatted output conversion

    SYNOPSIS
      #include <stdio.h>

      int printf(const char *format, ...);
      int fprintf(FILE *stream, const char *format, ...);
      int dprintf(int fd, const char *format, ...);
      int sprintf(char *str, const char *format, ...);
      int snprintf(char *str, size_t size, const char *format, ...);

      #include <stdarg.h>

      int vprintf(const char *format, va_list ap);
      int vfprintf(FILE *stream, const char *format, va_list ap);
      int vdprintf(int fd, const char *format, va_list ap);
      int vsprintf(char *str, const char *format, va_list ap);
      int vsnprintf(char *str, size_t size, const char *format, va_list ap);
    Как реализовать функцию с переменным числом аргументов и построить список аргументов, достаточно обратиться к примерам.
     
    Последнее редактирование: 26 ноя 2019
    Igor68 нравится это.
  3. Igor68

    Igor68 Гуру

    Если вы не обратили внимания то в #1 я приводил свой рабочий код, я применял va_list и реализовал, но в милионный раз повторюсь что вопрос не по работе со списком (там всё реализовано - уже и мозоли на языке/пальцах - одно и тоже и не я тролю, а меня)
    Вопрос можно ли сделать функцию с переменным числом аргументов, которые она передаёт функции вызываемой из неё? Потому как со списком аргументов уже работаю и пример указанный ещё до темы применен.
    #1
    #1
    ....
    #1
     
  4. Пример
    Код (Text):

    void PrintFError ( const char * format, ... )
    {
    char buffer[256];
    va_list args;
    va_start (args, format);
    vsprintf (buffer,format, args);
    perror (buffer);
    va_end (args);
    }
    "Вопрос можно ли сделать функцию с переменным числом аргументов,"
    Это функция PrintFError, она получает список аргументов.
    "которые она передаёт функции вызываемой из неё"
    из неё выполняется вызов vsprintf и передает ей список которые сама получила

    Вы и так знаете как построить список и передать через va_list. Что ещё требуется реализовать?
    Если нет сигнатуры с аргументом va_list придется построить большой switch на разное количество предварительно подсчитанных аргументов.
     
    Igor68 нравится это.
  5. На gcc есть ещё такие плюшки, которые позволяют выделить память на стеке, скопировать туда аргументы вызывающей функции и вызвать функцию с переменным количеством аргументов.
    Код (C):
    #include <stdio.h>
    #include <stdarg.h>
    void* __builtin_apply_args();
    void* __builtin_apply(void (*function)(), void *arguments, size_t size);
    void my_print (const char* fmt, ...) {
       __builtin_apply((void (*))printf, __builtin_apply_args(), 32);
    }
    int main () {
       float f = 1.234;
       my_print("Example: %d %X %s %f %p\n", 1, 123456789, "bla-bla", f, my_print);
       return 0;
    }
    Вывод
    Код (Text):
    Example: 1 75BCD15 bla-bla 1.234000 0x556ee49c564a
    Источник
     
    parovoZZ и Igor68 нравится это.
  6. Igor68

    Igor68 Гуру

    Спасибо проверю сейчас в KEIL uVision4 с RealView. Именно для него и тема. Кстати "подмены" Вы уже приводили пример ранее.
    В любом случае спасибо!
     
  7. Igor68

    Igor68 Гуру

    Код (Text):
    Rebuild target 'Target 1'
    assembling ADuC702x.s...
    compiling main.c...
    main.c(130): warning:  #1295-D: Deprecated declaration __builtin_apply_args - give arg types
    main.c(133): warning:  #167-D: argument of type "void *" is incompatible with parameter of type "void (*)()"
    main.c(145): warning:  #111-D: statement is unreachable
    linking...
    gp_print.axf: Error: L6218E: Undefined symbol __builtin_apply (referred from main.o).
    gp_print.axf: Error: L6218E: Undefined symbol __builtin_apply_args (referred from main.o).
    Target not created
    Это при замене на:
    Код (C++):
    void* __builtin_apply_args();
    void* __builtin_apply(void (*function)(), void *arguments, size_t size);
    void LCD_Printf (const char* fmt, ...) {
       __builtin_apply((void (*))printf, __builtin_apply_args(), 32);
    }
    При main:
    Код (C++):
    int main(void)
    {
            LCD_Printf("string:%s char:%c ", "testing", '2');
            LCD_Printf("int: %i %d", 1234, -4678);
            LCD_Printf("unsigned int: %u %u", 1234, 4678);
            LCD_Printf("hex: %x %X", 1234, 123);
            LCD_Printf("float:%.2f %f ", 3.1459, 3.1459 * 2.5);
            LCD_Printf("float:%.e %E ", 3.1459, -3.1459/2.5);
            while(1);
        return 0;
    }
    а:
    Код (C++):
    #include <stdio.h>
    #include <stdarg.h>
    Так же давно определены. Надо было сколько-то лет назад выбрать GCC (есть возможность его прикрутить), но проект надо только изменить/откорректировать. Заново это долго - много менять.
    А надо только заменить то что есть на один sprintf, что бы сформировать буфер для вывода на символьный жк экран прибора. Можно конечно всё заменить расстановкой этого sprintf везде. А хотел всё в одной функции. Хотел подменить (даже __stdout и т.п. думал "переставить") - компилятор не желает. По ходу он не из ветки GCC
     
    Последнее редактирование: 26 ноя 2019
  8. Igor68

    Igor68 Гуру

    Зато сколько косяков найдено при копании. Да ещё FIQ и IRQ ускорил... после чего на main времени больше выделяется, Укоротил время обработки клавиатуры и дисплея, оптимизировал формирование массива синусоиды для эталонного измерения по точкам. Изменил и фильтры и коррекцию для ШИМ формирования огибающей по точкам измерения АЦП.
    Устройство - генератор синусоиды с нагрузкой от единиц ом до бесконечности с выходной мощностью 60 Вт и напряжением выхода 3...60 в действующего(не амплитудного).
     
  9. Igor68

    Igor68 Гуру

    Ай спасибо ДРУЖИЩЕ!!!!!
    РЕСПЕКТ! РЕСПЕКТ! РЕСПЕКТ!
    Вот это именно то, что я искал. Ранее со списком не имел дела никогда.
    Спасибо!!!
     
  10. Сначала это
    Потом вот это
    Вы путаетесь в показаниях или я порой не понимаю что вы хотели сказать.
     
    Igor68 нравится это.
  11. Igor68

    Igor68 Гуру

    Да вот и сам не знаю... толи "как это по русски...", толи язык с костями. Даже и не знаю...
    Именно не сказал что надо получить список и передать его... а "как это по русски?" (шутка).
    Именно этот ответ и ждал и как уточнение выкладывал код.
    Как говориться "жареное... а вот что жареное? но неимоверно вкусно" или "больно! всем досталось... только не помню как называются"
    Простите, что заставил Вас быть телепатом.