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

Массив указателей на функции. Need help.

Добрый день!

Стоит следующая задача: есть некоторое количество функций func00, func01, ... , funcN. В зависимости от значения переменной необходимо вызвать либо func00, либо func01, и т.д. Причем городить конструкцию switch-case очень не хочется (условий получится больше 100).

 

Попробовал создать массив указателей на функции, следующим образом:

 

void func00(void)
{
    printf("func00");
}

void func01(void)
{
    printf("func01");
}

void test(void)
{
    void *func();
    int ptrs[2];
    char x;

    ptrs[0] = (int)func00;
    ptrs[1] = (int)func01;

    // пытаемся присвоить func() указатель на нужную функцию
    x = 0;
    func = (void*)ptrs[x];

    // вызов функци
    func();

}

 

При компиляции для строчки func = (void*)ptrs[x] выдается вполне ожидаемая ошибка - Error[Pe137]: expression must be a modifiable lvalue.

 

Что делать? :help:

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


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

Добрый день!

Стоит следующая задача: есть некоторое количество функций func00, func01, ... , funcN. В зависимости от значения переменной необходимо вызвать либо func00, либо func01, и т.д. Причем городить конструкцию switch-case очень не хочется (условий получится больше 100).

Что делать? :help:

не парьтесь, в Вашем случае ИАР сам сотворит такую таблицу, как раз, если Вы будете использовать switch-case

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


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

Добрый день!

Стоит следующая задача: есть некоторое количество функций func00, func01, ... , funcN. В зависимости от значения переменной необходимо вызвать либо func00, либо func01, и т.д. Причем городить конструкцию switch-case очень не хочется (условий получится больше 100).

 

Попробовал создать массив указателей на функции, следующим образом:

 

void func00(void)
{
    printf("func00");
}

void func01(void)
{
    printf("func01");
}

void test(void)
{
    void *func();
    int ptrs[2];
    char x;

    ptrs[0] = (int)func00;
    ptrs[1] = (int)func01;

    // пытаемся присвоить func() указатель на нужную функцию
    x = 0;
    func = (void*)ptrs[x];

    // вызов функци
    func();

}

 

При компиляции для строчки func = (void*)ptrs[x] выдается вполне ожидаемая ошибка - Error[Pe137]: expression must be a modifiable lvalue.

 

Что делать? :help:

void *func(); - это прототип функции. Указатель объявляется как void (* func)(); Вызов соответственно будет (*func)();

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


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

Вот так должно работать, только что проверил

 

void func00(void)
{
    printf("func00");
}

void func01(void)
{
    printf("func01");
}

void test(void)
{
    void (* func)();
    int ptrs[2];
    char x;

    ptrs[0] = (int)func00;
    ptrs[1] = (int)func01;

    
    x = 0;
    func = (void (*)())ptrs[x];

    

    func();
}

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


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

Спасибо всем откликнувшимся!

 

Соорудил вот такой код:

void func00(void)
{
    printf("func00\r\n");
}

void func01(void)
{
    printf("func01\r\n");
}

int __flash ptrs[2] = {(int)func00, (int)func01};

void test(void)
{
    ((void (*)())ptrs[0])();
    ((void (*)())ptrs[1])();
}

 

В симуляторе работает. Вот только, не понятно, каким образом IAR на этапе компиляции знает адреса функций func00, func01 во __flash...

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


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

В симуляторе работает. Вот только, не понятно, каким образом IAR на этапе компиляции знает адреса функций func00, func01 во __flash...
А все оче просто - раз вы вызывете что то по адресу, значит адрес во флэш - по другому быть не может...

 

 

 

Но все же рекомендую switch case - доверьтесь компилятору, на крайцний случай проверьте листинг - все будет шоколадно, так как вы хотите - через таблицу векторов функций

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


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

В симуляторе работает. Вот только, не понятно, каким образом IAR на этапе компиляции знает адреса функций func00, func01 во __flash...

 

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

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


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

Соорудил вот такой код:
А зачем вы делаете принудительное приведение указателя к типу int? Во-первых это требует лишней писанины, во-вторых ограничиваете указатель размером int (непереносимость), но главное - вы подавляете возможность компилятора отлавливать ошибки несоответствия типов:

void func00(void)
{
    printf("func00\r\n");
}

void func01(void)
{
    printf("func01\r\n");
}

typedef void (*pfunc_t)(void);

pfunc_t __flash ptrs[2] = {func00, func01};

void test(void)
{
    ptrs[0]();
    ptrs[1]();
}

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


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

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

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

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

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

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

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

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

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

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