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

 
 
 
Reply to this topicStart new topic
> C++ массив указателей на функцию, помогите разобраться.
Rusoil
сообщение Mar 6 2009, 20:13
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 47
Регистрация: 21-01-09
Пользователь №: 43 695



Имеем класс для работы с модемом SIM300. В данном классе есть методы вида SIM300::AT_XXX().
Имеем список enum с индексами методов, вид eAT_XXX.

В определенный момент нужно запускать метод установив соответствующий индекс. Можно сделать через switch-case так.
switch( eInd )
{
case eAT_XXX:
AT_XXX();
break;
...
}

Но так долго, нужно быстрее. Я попытался сделать массив указателей на функцию.

static void (__code __interwork SIM300::*pCmdFunc[eCMD_QNT] )() =
{
SIM300::AT_CPOWON,
...
}

Компилятор не ругается. т.е. вроде как все норм.
Но когда осуществляю вызов функции в одном из методов класса SIM300:

(pCmdFunc[eCmdInd])();

то компилятор выдает ошибку

Error[Pe109]: expression must have (pointer-to-) function type

Я использовал раньше массив указателей на функции, но на обычные функции, а не на методы класса. Там все работало.

Есть у кого-нибудь идеи? Может как-то по другому можно решить данную проблему?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 6 2009, 21:08
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Rusoil @ Mar 6 2009, 22:13) *
Я использовал раньше массив указателей на функции, но на обычные функции, а не на методы класса. Там все работало.
Я тоже. Использовал указатели на функции-члены только однажды, и мне удалось. Насколько я понимаю, вы не передаете имя объекта класса SIM300, для которого нужно вызвать функцию-член.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Mar 6 2009, 21:14
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Советую почитать тут: http://www.newty.de/fpt/index.html. Довольно внятно и много примеров.
Go to the top of the page
 
+Quote Post
HARMHARM
сообщение Mar 6 2009, 21:17
Сообщение #4


читатель даташитов
****

Группа: Свой
Сообщений: 853
Регистрация: 5-11-06
Из: Днепропетровск
Пользователь №: 21 999



Цитата(Сергей Борщ @ Mar 6 2009, 23:08) *
Я тоже. Использовал указатели на функции-члены только однажды, и мне удалось. Насколько я понимаю, вы не передаете имя объекта класса SIM300, для которого нужно вызвать функцию-член.

Я делал, тоже для SIM300 smile.gif
Вид такой:

Код
    struct TATCommand
    {
        unsigned short int timeOut;                 ///< timeout in seconds
        unsigned short int maxRetries;
        const char* theCommand;                     ///< AT command cstring
        void (TGsmParser::*reqOK)(const char*);     ///< function to call if request completed
        void (TGsmParser::*doReq)(const char*);     ///< function to call to invoke command
        void (TGsmParser::*retrExceeded)();         ///< function to call if all retries failed
    };

    TATCommand *atCommand;                          /// pointer to curent structure
    TATCommand basicATCommand[NumBasicATCommand];   ///< base config, imei, phonebook and SMS commands @todo add getImsi
    TATCommand gprsATCommand[NumGPRSATCommand];     ///< GPRS and TCP handling

Вызов происходит так:
Код
this->*atCommand[lastRequest].reqOK)(...);

Уродливо.
Потом плюнул на это, и переписал через иерархию классов с виртуальными методами. Куда красивее вышло и меньше путаницы.
Код
class TAtCommand
{
public:
    TAtCommand();
    // Instantiated functions
    virtual const char*  getCommand() const = 0;
    virtual unsigned int getTimeoutS() const;
    virtual unsigned int getMaxRetries() const;
    virtual unsigned int getPauseMs() const;
    virtual int doParseSetResult( char* data, int len ) const;
    virtual int doParseRequestResult( char* data, int len ) const;
    virtual void doHandleRetriesExceeded() const;
    virtual void doHandleTimeoutExceeded() const;
    bool canDoCommandRetry( const TAtCommand *commandToCheck ) const;
    int doReqest() const;                           ///< return: -1 wrong write, >=0 size writen data
    virtual int doSet( const char * value = 0 ) const;    ///< if overriden may provide different data
    void doDelayAndSetTimeout() const;
    static void clearReqSet();
    static ATCOMMAND_RESULT getStandardResult( char* data, int len, char &reslen );
    static void checkTimeout();
    static int tryProcessAnswer( char* buf, int len, int lookPos );
protected:
    friend class TmsgRdy;
    static const char *currSetValue;
    static const TAtCommand *lastReqest;
    static const TAtCommand *lastSet;
    static portTickType globTimeout;
    static unsigned short retries;
    static TGenericGsm *gsm;
    static unsigned short lastError;
};
Go to the top of the page
 
+Quote Post
Rusoil
сообщение Mar 7 2009, 14:46
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 47
Регистрация: 21-01-09
Пользователь №: 43 695



Цитата(sergeeff @ Mar 7 2009, 01:14) *
Советую почитать тут: http://www.newty.de/fpt/index.html. Довольно внятно и много примеров.



Спасибо, то что надо.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 8th July 2025 - 13:27
Рейтинг@Mail.ru


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