最近开发的项目使用C++开发,需要大量使用message id来调用函数。讨厌写成switch cased的结构,就想像之前在C语言使用函数指针table的方法,来调用成员函数。
之前使用C语言的话,还是比较方便的。但C++语言使用成员函数指针数组就比较麻烦。调试了一天,终于调通了。测试可以正常运行。下面是代码:
static MessageMap DTCMessageMapTable[Func_Total_Number] =
{
{Func_ReadDTCByID, 0x1122},
{Func_ReadAllDTCs, 0x1133},
{Func_UpdateDTCByID, 0x1144},
{Func_UpdateAllDTCs, 0x1155}
};
static DTC_STATUS_ST DTC_ShadowList[DTC_Total_Number] =
{
};
DTCAgent::DTCAgent()
{
m_FileLib = new FileLibrary;
fpCbk[Func_ReadDTCByID] = &DTCAgent::ReadDTCByID;
fpCbk[Func_ReadAllDTCs] = &DTCAgent::ReadAllDTCs;
fpCbk[Func_UpdateDTCByID] = &DTCAgent::UpdateDTCByID;
fpCbk[Func_ReadAllDTCs] = &DTCAgent::UpdateAllDTCs;
}
DTCAgent::~DTCAgent()
{
delete m_FileLib;
}
bool DTCAgent::ReadDTCToCache()
{
uint8_t len = sizeof(DTC_FILE_CONTEXT);
char* DTC_File_Buffer_Backup = new char[len];
if(m_FileLib->ReadDTCFile(DTC_File_Buffer_Backup, len))
{
memset(&DTC_File_Buffer, 0, len);
memcpy(&DTC_File_Buffer, DTC_File_Buffer_Backup, len);
delete [] DTC_File_Buffer_Backup;
return true;
}
else
{
delete []DTC_File_Buffer_Backup;
cout << "Read DTC File to Cache Failed" << endl;
return false;
}
}
bool DTCAgent::ReadDTCByID(uint8_t* data, uint8_t len)
{
uint8_t ListIndex;
uint8_t Ftb = data[3];
uint16_t DtcID = data[0]*256 + data[1];
for(ListIndex = 0; ListIndex < DTC_Total_Number; ListIndex++)
{
if(DTC_ShadowList[ListIndex].DtcID == DtcID)
{
if(DTC_ShadowList[ListIndex].Ftb == Ftb)
{
return true;
}
}
}
cout << "Read DTC by ID can not match DTC code" << endl;
return false;
}
bool DTCAgent::WriteDTC()
{
uint8_t len = sizeof(DTC_FILE_CONTEXT);
char* DTC_File_Buffer_Backup = new char[len];
memset(&DTC_File_Buffer_Backup, 0, len);
memcpy(DTC_File_Buffer_Backup, &DTC_File_Buffer, len);
if(m_FileLib->WriteDTCFile(DTC_File_Buffer_Backup, len))
{
delete [] DTC_File_Buffer_Backup;
return true;
}
else
{
delete [] DTC_File_Buffer_Backup;
cout << "Write DTC Data to File Failed" << endl;
return false;
}
}
bool DTCAgent::DTCAgentMainFunction(MessageST MData)
{
uint8_t FuncId = 0;
for(FuncId = Func_ReadDTCByID; FuncId < Func_Total_Number; FuncId++)
{
if(DTCMessageMapTable[FuncId].MsgID == MData.MsgID)
{
(this->*fpCbk[FuncId])(MData.data, MData.len);
return true;
}
}
cout << "DTC agent can not find match message id" << endl;
return false;
}
typedef enum
{
Func_ReadDTCByID = 0, //manager read DTC by ID
Func_ReadAllDTCs = 1, //manager read All DTCs
Func_UpdateDTCByID = 2, //manager update DTC by ID
Func_UpdateAllDTCs = 3, //manager update All DTCs
Func_Total_Number = 4
}Func_ID;
typedef struct
{
uint8_t DTCStatus[DTC_Total_Number];
uint16_t CRCFlag;
}DTC_FILE_CONTEXT;
typedef struct
{
uint32_t MsgID;
uint8_t len;
uint8_t data[20];
}MessageST;
typedef struct
{
uint8_t FuncID;
uint32_t MsgID;
} MessageMap;
/**
* @class DTCAgent
* @brief DTCAgent class to define the functionality/logic of DTCAgent
*/
class DTCAgent
{
public:
///@publicsection
/// @brief Default constructor.
DTCAgent(void);
/// @brief Default destructor.
virtual ~DTCAgent(void);
/// Needed by all applications to set into Controller task
/// @fn void init(void)
/// @brief Init function
/// @return true or false
void init(void);
bool DTCAgentMainFunction(MessageST data);
private:
bool ReadDTCToCache();
bool ReadDTCByID(uint8_t* data, uint8_t len);
bool WriteDTC();
void RequestAllDTCs();
uint16_t CalculCRC(uint8_t *data, uint32_t length);
private:
FileLibrary* m_FileLib;
FunctionCallBack DTCAgent::*fpCbk[Func_Total_Number];
};
美中不足的是,我想下面的代码能直接在数组里面一起赋值。不想单独赋值。希望知道怎么优化的同行,可以私信评论。
fpCbk[Func_ReadDTCByID] = &DTCAgent::ReadDTCByID;
fpCbk[Func_ReadAllDTCs] = &DTCAgent::ReadAllDTCs;
fpCbk[Func_UpdateDTCByID] = &DTCAgent::UpdateDTCByID;
fpCbk[Func_ReadAllDTCs] = &DTCAgent::UpdateAllDTCs;