Say I have the following definitions for function pointers:
typedef void(*Tmp112HardwareInit)();
typedef void(*Tmp112HardwareDeInit)();
typedef bool(*Tmp112HardwareIsBusy)();
I have an interface object to hold instances of the above function pointers:
typedef struct
{
Tmp112HardwareInit init;
Tmp112HardwareDeInit deinit;
Tmp112HardwareIsBusy is_busy;
} I2CInterface;
static I2CInterface _i2c_interface; // This is declared in module scope
Before accessing these function, I want to check if they've been assigned something. So instead of
_i2c_interface.init();
I want...
if (_i2c_interface.init) _i2c_interface.init();
else error = true;
I don't want to repeat these lines for each access of each variable in _i2c_interface
, so I want to write a function:
bool _SensorTMP112_InterfaceInit()
{
bool success = true;
if (_i2c_interface.init)
{
_i2c_interface.init();
}
else
{
success = false;
}
return success;
}
Now, I don't want to write a function for each of these function pointers in _i2c_interface
variable. I want a generic function, which will be called by other functions for each of these function pointers:
// Generic function
bool _SensorTMP112_InterfaceOperation(UnknownType fptr) // What should be UnknownType?
{
bool success = true;
if (fptr)
{
fptr();
}
else
{
success = false;
}
return success;
}
// Operation specific functions
bool _SensorTMP112_InterfaceInit()
{
return _SensorTMP112_InterfaceOperation(_i2c_interface.init);
}
bool _SensorTMP112_InterfaceDeInit()
{
return _SensorTMP112_InterfaceOperation(_i2c_interface.deinit);
}
bool _SensorTMP112_InterfaceIsBusy()
{
return _SensorTMP112_InterfaceOperation(_i2c_interface.is_busy);
}
My question is what should be the type of UnknownType
? Or is it even possible in standard C? Or is there any other way around for what I want to achieve? Not interested in non-standard solutions.
Quick'n'dirty preprocessor macro:
#define callfn(f) if(f) f(); else result = false
Then
callfn(_i2c_interface.init);
result = true;
callfn(_i2c_interface.deinit);
(when bool success
is earlier defined), or use it in functions:
bool _SensorTMP112_InterfaceInit()
{
bool success = true;
callfn(_i2c_interface.init);
return success;
}
(You can also embed the bool success
and return success
inside the macro as well).
But you shouldn't expose that macro (i.e. #undef callfn
after the functions bodies calling it) because it leaves many open doors.