Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Массив указателей на функции. Need help.
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
leo@intek
Добрый день!
Стоит следующая задача: есть некоторое количество функций 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.gif
prottoss
Цитата(leo@intek @ Dec 26 2006, 17:07) *
Добрый день!
Стоит следующая задача: есть некоторое количество функций func00, func01, ... , funcN. В зависимости от значения переменной необходимо вызвать либо func00, либо func01, и т.д. Причем городить конструкцию switch-case очень не хочется (условий получится больше 100).
Что делать? help.gif
не парьтесь, в Вашем случае ИАР сам сотворит такую таблицу, как раз, если Вы будете использовать switch-case
_Bill
Цитата(leo@intek @ Dec 26 2006, 13:07) *
Добрый день!
Стоит следующая задача: есть некоторое количество функций 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.gif

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

Код
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();
}
leo@intek
Спасибо всем откликнувшимся!

Соорудил вот такой код:
Код
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...
prottoss
Цитата(leo@intek @ Dec 26 2006, 18:07) *
В симуляторе работает. Вот только, не понятно, каким образом IAR на этапе компиляции знает адреса функций func00, func01 во __flash...
А все оче просто - раз вы вызывете что то по адресу, значит адрес во флэш - по другому быть не может...



Но все же рекомендую switch case - доверьтесь компилятору, на крайцний случай проверьте листинг - все будет шоколадно, так как вы хотите - через таблицу векторов функций
SasaVitebsk
Цитата(leo@intek @ Dec 26 2006, 14:07) *
В симуляторе работает. Вот только, не понятно, каким образом IAR на этапе компиляции знает адреса функций func00, func01 во __flash...


На этапе компиляции, - не знает. На этапе линковки - узнаёт и подставляет.
Сергей Борщ
Цитата(leo@intek @ Dec 26 2006, 13:07) *
Соорудил вот такой код:
А зачем вы делаете принудительное приведение указателя к типу 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]();
}
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.