I have defined interface:
typedef DataExchg_Status_T (*DataExchg_Iface_ReceiveDataClbk_T)(
void * p_self, uint8_t const * p_data, size_t size);
typedef struct DataExchg_Iface_Tag {
DataExchg_Status_T (*SendData)(void * p_self, uint8_t const * p_data, size_t size);
void (*RegisterReceiveDataClbk)(void * p_self,
DataExchg_Iface_ReceiveDataClbk_T receive_data_clbk,
void * p_receiver_instance);
void * pSelf;
} DataExchg_Iface_T;
and I use it in Object_A
.
typedef struct Object_A_Tag {
DataExchg_Iface_T * pIface;
} Object_A_T;
In Object_B
module
I have implementation of this interface:
typedef struct Object_B_Tag {
int value;
...
} Object_B_T;
DataExchg_Status_T SendData(Object_B_T * p_self, uint8_t const * p_data, size_t size) {
...
}
void RegisterReceiveDataClbk(Object_B_T * p_self,
DataExchg_Iface_ReceiveDataClbk_T receive_data_clbk,
void * p_receiver_instance) {
...
}
Everything is ok until I want to assign the above functions to the interface in Object_A:
Object_B object_b = {...};
Object_A object_a = {
.pIface = &(DataExchg_Iface_T){
.SendData = SendData,
.RegisterReceiveDataClbk = RegisterReceiveDataClbk,
.pSelf = &object_b
}
};
The problem is that I get incompatible pointer warning because one of the parameter: void * p_self
is not equal to Object_B_T * p_self
in interface implementation.
There are some possible solutions of this problem:
1. Cast to the interface function pointer:
SendData = (DataExchg_Status_T(*)(void *, DataExchg_Iface_ReceiveDataClbk_T, void *)SendData
This is the most convenient solution, but there are some strong evidences that this solution could lead to undefined behaviour: Casting a function pointer to another type
2. Implement interface exactly as is declared and cast the parameter in the function body:
This is the safest solution, but not the most convenient.
DataExchg_Status_T SendData(void * p_self, uint8_t const * p_data, size_t size) {
Object_B_T pSelf = p_self;
}
3. Cast to the interface function pointer when initialize interface (solution 1) and cast interface function to its implemented type every time when I use it:
This solution according to my knowledge should not lead to undefined behaviour.
object_b.pIface->(DataExchg_Status_T(*)(Object_B *, DataExchg_Iface_ReceiveDataClbk_T, void *)SendData(...)
And finally questions:
1) Can the solution 1 really lead to undefined behaviour in my case?
2) Is there any solution where I can have generic interface declaration with void instance pointer and specyfic implementation with specyfic instance pointer? (similar to solution 1)