Нестатическая функция-член, такая как CLASS1::ControlTransfer
, не может быть вызвана, не зная, какой объект CLASS1
будет вызывать ее.А необработанный указатель на функцию, подобную вашей 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*
) или другой логикекоторый на самом деле вызывает функции, в зависимости от того, что больше подходит.