【问题标题】:how send function address from class1 to class2如何将函数地址从class1发送到class2
【发布时间】:2019-01-03 13:56:51
【问题描述】:

c++11/arm编译器v6.9/keil5

我有 2 个类 (class1, class2) - 我想将一个函数地址从 class1 发送到类 2,但我不能 - 我必须将我的函数定义为静态的 - 但我不想这样做

// ---------------------------- CLASS1.CPP ----------------------------
void CLASS1::ControlTransfer(uint8_t Physical_EPn, uint8_t bEPStatus) {
 // ...
}

void CLASS1::init() {
    class2.intHandler(2, ControlTransfer); // error: reference to non-static member function must be called
}

// ---------------------------- CLASS2.H ----------------------------
typedef void (TFnEPIntHandler)  (uint8_t Physical_EPn, uint8_t bEPStatus);

// ---------------------------- CLASS2.CPP ----------------------------
TFnEPIntHandler *_apfnEPIntHandlers[16];

void CLASS2::intHandler( uint8_t num, TFnEPIntHandler *pfnHandler ) {
    _apfnEPIntHandlers[ num ] = pfnHandler;
}

// _apfnEPIntHandlers used in my interrupt function

【问题讨论】:

    标签: c++11 static arm keil


    【解决方案1】:

    如果不知道要调用哪个 CLASS1 对象,就无法调用像 CLASS1::ControlTransfer 这样的非静态成员函数。指向像您的 TFnEPIntHandler 这样的函数的原始指针不包含足够的信息来指定该对象。

    如果可以,请考虑将原始函数指针更改为更灵活的std::function 类型:

    // In a header file:
    #include <functional>
    using TFnEPIntHandler = std::function<void(uint8_t, uint8_t)>;
    
    // TFnEPIntHandler should now be used directly, not as a pointer.
    // (Note a std::function can "act like" a null pointer.)
    TFnEPIntHandler _apfnEPIntHandlers[16];
    void CLASS2::intHandler( uint8_t num, TFnEPIntHandler pfnHandler ) {
        _apfnEPIntHandlers[ num ] = std::move(pfnHandler);
    }
    
    // Replace CLASS1::init():
    void CLASS1::init() {
        // Use a lambda which captures the "this" pointer and can be
        // converted to the std::function type.  The function must not
        // be used after this CLASS1 object is destroyed!
        class2.intHandler(2, [this](uint8_t Physical_EPn, uint8_t bEPStatus)
            { ControlTransfer(Physical_EPn, bEPStatus); });
    }
    

    如果std::function 不是一个选项,因为您需要与 C 代码接口,您可以在函数类型中添加一个额外的 void* 参数,并使用将指针转换为类类型的包装函数来调用真实的非静态成员函数。例如:

    class CLASS1 {
    // ...
    private:
        static void ControlTransferCB(uint8_t Physical_EPn,
                                      uint8_t bEPStatus,
                                      void* extra)
        {
            static_cast<CLASS1*>(extra)->ControlTransfer(Physical_EPn, bEPStatus);
        }
    // ...
    };
    

    额外的void* 参数可以提供给CLASS2::intHandler(这意味着应该有一个函数指针结构数组和额外的void* 数据),或者提供给实际调用函数的其他逻辑,以更多者为准合适。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多