函数指针 如:void (*oper)(ChainBinTreee *p)

  在C语言中,一个函数总是占用一段连续的内存区,而函数名就是该函数所占内存区的首地址。我们可以把函数的这个首地址(或称入口地址)赋予一个指针变量,使该指针变量指向该函数。然后通过指针变量就可以找到并调用这个函数。我们把这种指向函数的指针变量称为“函数指针变量”。
函数指针变量定义的一般形式为:
类型说明符 (*指针变量名)();
其中“类型说明符”表示被指函数的返回值的类型。“(* 指针变量名)”表示“*”后面的变量是定义的指针变量。最后的空括号表示指针变量所指的是一个函数。
例如:
int (*pf)();
表示pf是一个指向函数入口的指针变量,该函数的返回值(函数值)是整型。
【例】本例用来说明用指针形式实现对函数调用的方法。
int max(int a,int b){
if(a>b)return a;
else return b;
}
main(){
int max(int a,int b);
int(*pmax)();
int x,y,z;
pmax=max;
printf("input two numbers:\n");
scanf("%d%d",&x,&y);
z=(*pmax)(x,y);
printf("maxmum=%d",z);
}

从上述程序可以看出用,函数指针变量形式调用函数的步骤如下:
1) 先定义函数指针变量,如后一程序中第9行 int (*pmax)();定义 pmax为函数指针变量。
2) 把被调函数的入口地址(函数名)赋予该函数指针变量,如程序中第11行 pmax=max;
3) 用函数指针变量形式调用函数,如程序第14行 z=(*pmax)(x,y);
4) 调用函数的一般形式为:
(*指针变量名) (实参表)
使用函数指针变量还应注意以下两点:
a) 函数指针变量不能进行算术运算,这是与数组指针变量不同的。数组指针变量加减一个整数可使指针移动指向后面或前面的数组元素,而函数指针的移动是毫无意义的。
b) 函数调用中"(*指针变量名)"的两边的括号不可少,其中的*不应该理解为求值运算,在此处它只是一种表示符号。
 
 

在《C陷阱与缺陷》中有这样一段描述:

fp是一个函数指针,那么*fp就是该指针所指向的函数,所以(*fp)()就是调用该函数的方式。ANSI C标准允许程序员将上式简写为fp(),但是一定要记住这种写法只是一种简写形式。

转载于:https://www.cnblogs.com/rednodel/p/4047660.html

/*!Copyright (c) 2024 TP-LINK Technologies CO.,LTD. *All rights reserved. * *\file dalL2_port.c *\brief dalL2_port.c source file * *\author liuchang *\version 1.0.0 *\date 20/02/2025 */ #include <stdio.h> #include "fepTypes.h" #include "fepDefs.h" #include "tpDbg/tpdebug.h" #include "common/dmpComDef.h" #include "common/applError.h" #include "midware/dal.h" #include "midware/dalAdo.h" #include "dalL2_port.h" #include "l2/port/portPub.h" #include "l2/port/dalPortPub.h" #include "l2/port/errPort.h" #include "userPort/up_spec.h" #include "userPort/user_port.h" #include "userPort/up_str.h" #include "userPort/up_property.h" static int _dalPortStateSet(user_port up, UINT8 state) { if(PORT_ENABLE == state) { } else { } return ERR_NO_ERROR; } static int _dalPortSpeedDuplexSet(user_port up, UINT32 spd, UINT32 dpx) { return ERR_NO_ERROR; } static int _dalPortConfigHandle(dal_ado_t *adoi, void *handler, char *key) { UINT32 speed = 0; UINT32 duplex = 0; UINT8 state = 0; user_port up = {}; BOOL isSpeedDuplex = FALSE; DAL_PORT_KEY_CFG_PARSE(key, up); if(DAL_ADOI_ENTRY_KEY_EMPTY(handler)) { } else { DBG("key %s", key); DAL_ADOI_ENTRY_FIELD_LOOP(handler, key) { if (DAL_ADOI_ENTRY_FIELD_MATCH(handler, DAL_PORT_K_CFG_F_SPEED_U32)) { isSpeedDuplex = TRUE; dalAdoiGetEntryUI32(adoi, DAL_PORT_K_CFG, &speed); } if (DAL_ADOI_ENTRY_FIELD_MATCH(handler, DAL_PORT_K_CFG_F_DUPLEX_U32)) { isSpeedDuplex = TRUE; dalAdoiGetEntryUI32(adoi, DAL_PORT_K_CFG, &duplex); } if (DAL_ADOI_ENTRY_FIELD_MATCH(handler, DAL_PORT_K_CFG_F_STATE_U8)) { dalAdoiGetEntryUI8(adoi, DAL_PORT_K_CFG, &state); DBG("set state %hhu", state); _dalPortStateSet(up, state); } } if(isSpeedDuplex) { DBG("speed %d, duplex %d up %d", speed, duplex, UP_INDEX(up)); _dalPortSpeedDuplexSet(up, speed, duplex); } } return ERR_NO_ERROR; } static int _dalPortHandler(dal_ado_t *adoi, dal_attr *attr) { void *handler = NULL; if (NULL != (handler = DAL_ADOI_ENTRY(adoi, DAL_PORT_K_CFG))) { DAL_ADOI_ENTRY_LOOP(handler) { char *key = NULL; if(NULL == (key = DAL_ADOI_ENTRY_KEY(handler))) { DBG_ERR("key is NULL"); continue; } /* KEY inner field&value loop */ if(DAL_ADOI_ENTRY_KEY_MATCH(handler, DAL_PORT_K_CFG_ALL)) { _dalPortConfigHandle(adoi, handler, key); } } } else { } return ERR_NO_ERROR; } static int _dalL2_portDataInit() { int ret = ERR_NO_ERROR; dal_ado_t *adoi=NULL; int index = 0; user_port up = {}; valid_uplist valid_uplist = NULL; if (NULL==(adoi = dalAdoiCreate(DMP_DEV_NAME_SWITCHMAC, DAL_MOD_PORT, DAL_CFG_TYPE_ENTRY | DAL_CFG_TYPE_NOPUB))) { return ERR_NO_MEMORY; } valid_uplist_init(&valid_uplist, 0); valid_uplist_get(&valid_uplist, 0); PFM_IF_FAIL_DONE_RET(ret, dalAdoiEntryTableAppend(adoi, DAL_PORT_K_CFG), ERR_INIT); PFM_IF_FAIL_DONE_RET(ret, dalAdoiEntryOperAppend(adoi, DAL_PORT_K_CFG, DAL_OPER_CFG), ERR_INIT); UP_ITER_VALID(valid_uplist, index, up) { /*DMP module APPDEMO ado init */ char key[PORT_KEY_LEN] = {}; DAL_PORT_KEY_CFG_CREATE_BY_UP(key, index); DBG("inti port %d/%d/%d index %d is valid, UP_IS_VALID %d", UP_UNIT(up), UP_SLOT(up), UP_PORT(up), index, UP_IS_VALID(up)); PFM_IF_FAIL_DONE_RET(ret, dalAdoiAddEntryKey(adoi, DAL_PORT_K_CFG, key, UP_INDEX(up)), ERR_INIT); PFM_IF_FAIL_DONE_RET(ret, dalAdoiAddEntryUI8(adoi, DAL_PORT_K_CFG, DAL_PORT_K_CFG_F_STATE_U8, DAL_PORT_STATE_DEFAULT), ERR_INIT); PFM_IF_FAIL_DONE_RET(ret, dalAdoiAddEntryUI32(adoi, DAL_PORT_K_CFG, DAL_PORT_K_CFG_F_SPEED_U32, DAL_PORT_SPEED_DEFAULT), ERR_INIT); PFM_IF_FAIL_DONE_RET(ret, dalAdoiAddEntryUI32(adoi, DAL_PORT_K_CFG, DAL_PORT_K_CFG_F_DUPLEX_U32, DAL_PORT_DUPLEX_DEFAULT), ERR_INIT); PFM_IF_FAIL_DONE_RET(ret, dalAdoiAddEntryUI8(adoi, DAL_PORT_K_CFG, DAL_PORT_K_CFG_F_FLOWCTRL_U8, DAL_PORT_FLOWCTRL_DEFAULT), ERR_INIT); } PFM_IF_FAIL_DONE_RET(ret, dalSet(adoi), ERR_INIT); done: if(NULL != valid_uplist) { valid_uplist_free(&valid_uplist); } if(NULL != adoi) { dalAdoiDestroy(adoi); } return ret; } int dalL2_portInit() { APPL_IF_ERR_RET(_dalL2_portDataInit()); PFM_IF_FAIL_RET_VAL(dalHandlerReg(DAL_MOD_PORT, _dalPortHandler), ERR_INIT); return ERR_NO_ERROR; } /*!Copyright (c) 2010-2011 TP-LINK Technologies CO.,LTD. *All rights reserved. * *\file dalL2_port.c *\brief * *\author Yang jingjing *\version *\date 2025-03-27 */ /**************************************************************************************************/ /* INCLUDE_FILES */ /**************************************************************************************************/ #include "fepTypes.h" #include "fepDefs.h" #include "fepPfm.h" #include "tpDbg/tpdebug.h" #include "common/applError.h" #include "timer/timer.h" #include "gr/gr_client.h" #include "gr/gr_log.h" #include "midware/dal.h" #include "userPort/user_port.h" #include "l2/port/dalPortPub.h" #include "l2/port/portPub.h" #include "l2/port/errPort.h" #include "dal/dalL2_port.h" #include "hi/hiL2_port.h" #include "dmp/dmpPub.h" /**************************************************************************************************/ /* DEFINES */ /**************************************************************************************************/ /**************************************************************************************************/ /* TYPES */ /**************************************************************************************************/ /**************************************************************************************************/ /* EXTERN_PROTOTYPES */ /**************************************************************************************************/ /**************************************************************************************************/ /* LOCAL_PROTOTYPES */ /**************************************************************************************************/ /**************************************************************************************************/ /* VARIABLES */ /**************************************************************************************************/ /**************************************************************************************************/ /* LOCAL_FUNCTIONS */ /**************************************************************************************************/ /* * @brief 根据ASICDB中的数据 调用Hi层接口配置镜像功能. 根据mirrorPortIdx字段的值 判断clear后是否重新set * * @param[in] * * @return int * */ static int _dalL2PortMirrorSet(MIRRORED_PORT_INFO *mirroredPortInfo, UINT8 entryNum) { DBG_ALZ("Enter _dalL2PortMirrorSet ......"); if (0 == mirroredPortInfo[0].mirrorPortIdx) { DBG_ALZ("mirror state off"); hiPortMirrorClearAll(); return ERR_NO_ERROR; } UINT32 mirrorMode; char mirroredPortStr[200]; mirroredPortStr[0] = '\0'; for (int i = 0; i < entryNum; i++) { if (MIRROR_INGRESS == mirroredPortInfo[i].mirrorMode) { sprintf(mirroredPortStr + strlen(mirroredPortStr), "%d ", mirroredPortInfo[i].mirroredPortIdx - 1); } else if (MIRROR_EGRESS == mirroredPortInfo[i].mirrorMode) { sprintf(mirroredPortStr + strlen(mirroredPortStr), "%dt ", mirroredPortInfo[i].mirroredPortIdx - 1); } else if (MIRROR_BOTH == mirroredPortInfo[i].mirrorMode) { sprintf(mirroredPortStr + strlen(mirroredPortStr), "%d %dt ", mirroredPortInfo[i].mirroredPortIdx - 1, mirroredPortInfo[i].mirroredPortIdx - 1); } else { DBG_ERR("mirror mode error! "); return ERR_BAD_PARAM; } } DBG_ALZ("mirrorPort[%u], mirroredPortsStr[%s]", mirroredPortInfo[0].mirrorPortIdx - 1, mirroredPortStr); hiPortMirrorClearAll(); hiPortMirrorSet(mirroredPortInfo[0].mirrorPortIdx, mirroredPortStr); return ERR_NO_ERROR; } static int _dalL2PortMirrorDataGet(MIRRORED_PORT_INFO *mirroredPortInfo, UINT8 *entryNum) { DBG_ALZ("Enter _dalL2PortMirrorDataGet ......"); int ret = ERR_NO_ERROR; void *tblHandler = NULL; char *key = NULL; dal_ado_t *adoi = dalAdoiCreate(DMP_DEV_NAME_DEMO, DAL_MOD_PORT, DAL_CFG_TYPE_ENTRY); DMP_NULL_DONE_RETVAL(adoi, ret, ERR_NO_MEMORY); DMP_NOTEQUAL_DONE_RETVAL(PFM_ERR_C_OK, dalAdoiEntryTableAppend(adoi, DAL_PORT_E_K_MONITOR_PORT), ret, ERR_BAD_PARAM); DMP_NOTEQUAL_DONE_RETVAL(PFM_ERR_C_OK, dalAdoiEntryOperAppend(adoi, DAL_PORT_E_K_MONITOR_PORT, DAL_OPER_GET_RANGE), ret, ERR_BAD_PARAM); dalAdoiEntryRangeArgsAppend(adoi, DAL_PORT_E_K_MONITOR_PORT, TRUE, 0, -1); DMP_NOTEQUAL_DONE_RETVAL(PFM_ERR_C_OK, dalGet(adoi), ret, ERR_BAD_PARAM); DAL_ADOI_DBG_DISP(adoi); DAL_ADOI_ENTRY_ITER_ALL(adoi, tblHandler) { DBG_ALZ("loop of entry table name[%s]", DAL_ENTRY_TBL_NAME(tblHandler)); DAL_ADOI_ENTRY_LOOP(tblHandler) { if (NULL == (key = DAL_ADOI_ENTRY_KEY(tblHandler)) || !DAL_ADOI_ENTRY_KEY_MATCH(tblHandler, DAL_PORT_E_K_MONITOR_PORT_ALL)) { DBG_ERR("Invalid key %s !", key); continue; } if (DAL_ADOI_ENTRY_KEY_EMPTY(tblHandler)) { DBG_ALZ("dal operation [delete] mirror port"); } else { DAL_PORT_KEY_MONITOR_PORT_PARSE(key, mirroredPortInfo[*entryNum].mirroredPortIdx); DBG_ALZ("key[%s], mirroredUpIdx[%u]", key, mirroredPortInfo[*entryNum].mirroredPortIdx); DAL_ADOI_ENTRY_FIELD_LOOP(tblHandler, key) { if (DAL_ADOI_ENTRY_FIELD_MATCH(tblHandler, DAL_PORT_E_K_MONITOR_PORT_F_MODE_U32)) { dalAdoiGetEntryUI32(adoi, DAL_PORT_E_K_MONITOR_PORT, &mirroredPortInfo[*entryNum].mirrorMode); } if (DAL_ADOI_ENTRY_FIELD_MATCH(tblHandler, DAL_PORT_E_K_MONITOR_PORT_F_SESSION_ID_U8)) { dalAdoiGetEntryUI8(adoi, DAL_PORT_E_K_MONITOR_PORT, &mirroredPortInfo[*entryNum].mirrorPortIdx); } } } (*entryNum)++; } } done: DMP_FREE_TPDAL(adoi); return ret == PFM_ERR_C_OK ? ERR_NO_ERROR : ret; } static int _dalL2PortFlowCtrlGet(user_port up, UINT8 *flowCtrl) { int ret = ERR_NO_ERROR; dal_ado_t *adoi = NULL; UINT32 upIdx = 0; char key[PORT_KEY_LEN] = {}; CHAR *keyStr = NULL; void *handler = NULL; UP_TO_IDX(up, upIdx); DAL_PORT_KEY_CFG_CREATE_BY_UP(key, upIdx); adoi = dalAdoiCreate(DMP_DEV_NAME_SWITCHMAC, DAL_MOD_PORT, DAL_CFG_TYPE_ENTRY); DMP_NULL_DONE_RETVAL(adoi, ret, ERR_NO_MEMORY); DMP_NOTEQUAL_DONE_RETVAL(PFM_ERR_C_OK, dalAdoiEntryTableAppend(adoi, DAL_PORT_K_CFG), ret, ERR_PORT_EXEC_TPDAL); DMP_NOTEQUAL_DONE_RETVAL(PFM_ERR_C_OK, dalAdoiEntryOperAppend(adoi, DAL_PORT_K_CFG, DAL_OPER_GET_F), ret, ERR_PORT_EXEC_TPDAL); DMP_NOTEQUAL_DONE_RETVAL(PFM_ERR_C_OK, dalAdoiAddEntryKey(adoi, DAL_PORT_K_CFG, key, upIdx), ret, ERR_PORT_EXEC_TPDATA); DMP_NOTEQUAL_DONE_RETVAL(PFM_ERR_C_OK, dalAdoiAddEntryField(adoi, DAL_PORT_K_CFG, DAL_PORT_K_CFG_F_FLOWCTRL_U8), ret, ERR_PORT_EXEC_TPDATA); DMP_NOTEQUAL_DONE_RETVAL(PFM_ERR_C_OK, dalGet(adoi), ret, ERR_PORT_EXEC_TPDATA); if (NULL != (handler = DAL_ADOI_ENTRY(adoi, DAL_PORT_K_CFG))) { DAL_ADOI_ENTRY_LOOP(handler) { if (NULL== (keyStr = DAL_ADOI_ENTRY_KEY(handler)) || !DAL_ADOI_ENTRY_KEY_MATCH(handler, DAL_PORT_K_CFG_ALL)) { continue; } if (DAL_ADOI_ENTRY_KEY_EMPTY(handler)) { DBG_ALZ("key with no fields"); } else { DAL_ADOI_ENTRY_FIELD_LOOP(handler, keyStr) { if (DAL_ADOI_ENTRY_FIELD_MATCH(handler, DAL_PORT_K_CFG_F_FLOWCTRL_U8)) { dalAdoiGetEntryUI8(adoi, DAL_PORT_K_CFG, flowCtrl); } } } } } done: DMP_FREE_TPDAL(adoi); return ret; } static int _setNgmodeStr(IN UINT32 duplex, IN UINT32 speed, OUT char *str) { int ret = ERR_NO_ERROR; APPL_ENSURE_RET(UP_SPEED_TYPE_IS_VALID(speed) && UP_DUPLEX_TYPE_IS_VALID(duplex)); int speedValArr[UP_ABILITY_SPEED_END] = PORT_SPEED_VALUE; UINT32 speedVal = 0; switch (duplex) { case PORT_DUPLEX_AUTO: if (PORT_SPEED_AUTO == speed) { snprintf(str, SWLIB_SET_STR_LEN, "auto"); goto done; } else { GR_PRINT_ERROR("Bad Param. speed[%u] duplex[%u]", speed, duplex); ret = ERR_BAD_PARAM; goto done; } break; case PORT_HALF: speedVal = speedValArr[speed]; snprintf(str, SWLIB_SET_STR_LEN, "%uMH", speedVal); break; case PORT_FULL: speedVal = speedValArr[speed]; snprintf(str, SWLIB_SET_STR_LEN, "%uMF", speedVal); break; default: ret = ERR_BAD_PARAM; goto done; } done: return ret; } static int _dalL2PortSpeedDuplexSet(user_port up, UINT32 spd, UINT32 dpx, UINT8 flowCtrl) { int ret = ERR_NO_ERROR; char ngModeStr[SWLIB_SET_STR_LEN] = {}; char flowCtrlStr[SWLIB_SET_STR_LEN] = {}; DMP_NOTEQUAL_DONE_RETVAL(ERR_NO_ERROR, _setNgmodeStr(dpx, spd, ngModeStr), ret, ERR_BAD_PARAM); switch (flowCtrl) { case PORT_FLOWCTRL_DISABLE: snprintf(flowCtrlStr, SWLIB_SET_STR_LEN, "off"); break; case PORT_FLOWCTRL_ENABLE: snprintf(flowCtrlStr, SWLIB_SET_STR_LEN, "on"); break; default: ret = ERR_BAD_PARAM; DBG_ERR("Bad Param. upIdx[%u] flowCtrl[%hhu]", UP_INDEX(up), flowCtrl); goto done; } DBG_ALZ("ngModeStr[%s] flowCtrlStr[%s]", ngModeStr, flowCtrlStr); DMP_NOTEQUAL_DONE_RETVAL(ERR_NO_ERROR, hiPortSpeedDuplexSet(UP_INDEX(up), ngModeStr, flowCtrlStr), ret, ERR_BAD_PARAM); done: return ret; } static int _dalPortConfigHandle(dal_ado_t *adoi, void *tblHandler, char *key) { int ret = ERR_NO_ERROR; UINT32 speed = 0; UINT32 duplex = 0; UINT8 state = 0; UINT8 flowCtrl = 0, cfgFlowCtrl = 0; BOOL isSpeedDuplex = FALSE; user_port up = {}; DAL_PORT_KEY_CFG_PARSE(key, up); APPL_ENSURE_RET(!UP_IS_USB_PORT(up)); if (DAL_ADOI_ENTRY_KEY_EMPTY(tblHandler)) { DBG_ALZ("dal operation [delete] port. key[%s]", key); } else { DAL_ADOI_ENTRY_FIELD_LOOP(tblHandler, key) { if (DAL_ADOI_ENTRY_FIELD_MATCH(tblHandler, DAL_PORT_K_CFG_F_SPEED_U32)) { isSpeedDuplex = TRUE; dalAdoiGetEntryUI32(adoi, DAL_PORT_K_CFG, &speed); } if (DAL_ADOI_ENTRY_FIELD_MATCH(tblHandler, DAL_PORT_K_CFG_F_DUPLEX_U32)) { isSpeedDuplex = TRUE; dalAdoiGetEntryUI32(adoi, DAL_PORT_K_CFG, &duplex); } if (DAL_ADOI_ENTRY_FIELD_MATCH(tblHandler, DAL_PORT_K_CFG_F_STATE_U8)) { dalAdoiGetEntryUI8(adoi, DAL_PORT_K_CFG, &state); // 设置端口状态 DMP_NOTEQUAL_DONE_RETVAL(ERR_NO_ERROR, hiPortStateSet(UP_INDEX(up), state), ret, ERR_NOT_SET); } if (DAL_ADOI_ENTRY_FIELD_MATCH(tblHandler, DAL_PORT_K_CFG_F_FLOWCTRL_U8)) { dalAdoiGetEntryUI8(adoi, DAL_PORT_K_CFG, &flowCtrl); // 设置端口流控状态 可以单独下发on或off DMP_NOTEQUAL_DONE_RETVAL(ERR_NO_ERROR, hiPortFlowCtrlSet(UP_INDEX(up), flowCtrl), ret, ERR_NOT_SET); } } } if(isSpeedDuplex) { DBG_ALZ("upIdx[%d] speed[%u] duplex[%u]", UP_INDEX(up), speed, duplex); // 配置端口速率和双工模式 流控 swconfig dev switch0 port 9 set port-para "off 10MF" 设置时需要获取流控状态 一起下发 // 从asicDB中获取up的流控状态 DMP_NOTEQUAL_DONE_RETVAL(ERR_NO_ERROR, _dalL2PortFlowCtrlGet(up, &cfgFlowCtrl), ret, ERR_NOT_SET); DMP_NOTEQUAL_DONE_RETVAL(ERR_NO_ERROR, _dalL2PortSpeedDuplexSet(up, speed, duplex, cfgFlowCtrl), ret, ERR_NOT_SET); } done: return ret; } static int _dalL2PortHandle(dal_ado_t *adoi, dal_attr *attr) { // D("L2 port handle"); void *tblHandler = NULL; DBG_ALZ("Enter _dalL2PortHandle ......"); int ret = ERR_NO_ERROR; DAL_ADOI_DBG_DISP(adoi); // DAL_PORT_PORTCFG_TBL if (NULL != (tblHandler = DAL_ADOI_ENTRY(adoi, DAL_PORT_K_CFG))) { DAL_ADOI_ENTRY_LOOP(tblHandler) { char *key = NULL; if (NULL == (key = DAL_ADOI_ENTRY_KEY(tblHandler)) || !DAL_ADOI_ENTRY_KEY_MATCH(tblHandler, DAL_PORT_K_CFG_ALL)) { DBG_ERR("Invalid key %s !", key); continue; } DMP_NOTEQUAL_DONE_RETVAL(ERR_NO_ERROR, _dalPortConfigHandle(adoi, tblHandler, key), ret, ERR_NOT_SET); } } // mirror port handle if (NULL != (tblHandler = DAL_ADOI_ENTRY(adoi, DAL_PORT_E_K_MONITOR))) { // DBG_ALZ("mirror port entry cfg"); DAL_ADOI_ENTRY_LOOP(tblHandler) { char *key = NULL; UINT32 dstUpIdx = 0; UINT16 dst_rspan_vlan_id = UINT16_MAX; UINT16 src_rspan_vlan_id = UINT16_MAX; if (NULL == (key = DAL_ADOI_ENTRY_KEY(tblHandler)) || !DAL_ADOI_ENTRY_KEY_MATCH(tblHandler, DAL_PORT_E_K_MONITOR_ALL)) { DBG_ERR("Invalid key %s !", key); continue; } // DBG_ALZ("key [%s]", key); if (DAL_ADOI_ENTRY_KEY_EMPTY(tblHandler)) { DBG_ALZ("dal operation delete mirror port. key[%s]", key); /* @STUB_BEGIN [l2] [yangjingjing] [2025-04-16] */ /* 打桩原因:FEP提供的L2 port功能不支持删除监控口 删除对应key的dalSet暂未适配 */ //note 具体操作: clear监控口操作暂未实现 (操作: 清空监控口配置) /* @STUB_END */ } else { DBG_ALZ("dal operation [cfg] mirror port. key[%s]", key); /* KEY inner field&value loop */ DAL_ADOI_ENTRY_FIELD_LOOP(tblHandler, key) { if (DAL_ADOI_ENTRY_FIELD_MATCH(tblHandler, DAL_PORT_E_K_MONITOR_F_DST_UPIDX_U32)) { dalAdoiGetEntryUI32(adoi, DAL_PORT_E_K_MONITOR, &dstUpIdx); } if (DAL_ADOI_ENTRY_FIELD_MATCH(tblHandler, DAL_PORT_E_K_MONITOR_F_DST_REMOTE_VLAN_ID_U16)) { dalAdoiGetEntryUI16(adoi, DAL_PORT_E_K_MONITOR, &dst_rspan_vlan_id); } if (DAL_ADOI_ENTRY_FIELD_MATCH(tblHandler, DAL_PORT_E_K_MONITOR_F_SRC_REMOTE_VLAN_ID_U16)) { dalAdoiGetEntryUI16(adoi, DAL_PORT_E_K_MONITOR, &src_rspan_vlan_id); } } DBG_ALZ("dstUpIdx: %u, dst_rspan_vlan_id: %hu, src_rspan_vlan_id: %hu", dstUpIdx, dst_rspan_vlan_id, src_rspan_vlan_id); } } } // mirrored Ports handle if (NULL != (tblHandler = DAL_ADOI_ENTRY(adoi, DAL_PORT_E_K_MONITOR_PORT))) { char *key = NULL; UINT32 mirroredUpIdx = 0; UINT32 mirrorMode = 0; UINT8 sessionId = 0; MIRRORED_PORT_INFO mirroredPorts[INNER_UP_PORT_MAX]; UINT8 entryNum = 0; DAL_ADOI_ENTRY_LOOP(tblHandler) { if (NULL == (key = DAL_ADOI_ENTRY_KEY(tblHandler)) || !DAL_ADOI_ENTRY_KEY_MATCH(tblHandler, DAL_PORT_E_K_MONITOR_PORT_ALL)) { DBG_ERR("Invalid key %s !", key); continue; } DAL_PORT_KEY_MONITOR_PORT_PARSE(key, mirroredUpIdx); // DBG_ALZ("key [%s], mirroredUpIdx [%u]", key, mirroredUpIdx); if (DAL_ADOI_ENTRY_KEY_EMPTY(tblHandler)) { /* DAL operation is DAL_OPER_CLR */ DBG_ALZ("dal operation [delete] mirrored ports. key[%s]", key); } else { DBG_ALZ("dal operation [cfg] mirrored ports. key[%s]", key); DAL_ADOI_ENTRY_FIELD_LOOP(tblHandler, key) { if (DAL_ADOI_ENTRY_FIELD_MATCH(tblHandler, DAL_PORT_E_K_MONITOR_PORT_F_MODE_U32)) { dalAdoiGetEntryUI32(adoi, DAL_PORT_E_K_MONITOR_PORT, &mirrorMode); } if (DAL_ADOI_ENTRY_FIELD_MATCH(tblHandler, DAL_PORT_E_K_MONITOR_PORT_F_SESSION_ID_U8)) { dalAdoiGetEntryUI8(adoi, DAL_PORT_E_K_MONITOR_PORT, &sessionId); } } DBG_ALZ("mirroredUpIdx [%u], mirrorMode [%u], sessionId [%hhu]", mirroredUpIdx, mirrorMode, sessionId); // 被监控口配置下发 从asicDB中获取所有被监控口条目 并clear旧配置 set新配置 _dalL2PortMirrorDataGet(mirroredPorts, &entryNum); // for (int i = 0; i < entryNum; i++) // { // DBG_ALZ("i[%d], mirroredPort[%u], mode[%u], mirrorPort[%hhu]", i, mirroredPorts[i].mirroredPortIdx, mirroredPorts[i].mirrorMode, mirroredPorts[i].mirrorPortIdx); // } _dalL2PortMirrorSet(mirroredPorts, entryNum); } } } // mib clear handle DAL_ADOI_ACTION_LOOP(adoi) { char *key = NULL; char *field = NULL; UINT64 upIdx = UINT64_MAX; DBG_ALZ("_dalL2PortHandle: [mibclear action]"); if (NULL == (key = DAL_ADOI_ACTION_KEY(adoi))) { break; } DBG_ALZ("key: %s", key); if (STR_EQUAL(key, DAL_PORT_A_K_MIBCLR)) { if (DAL_ADOI_ACTION_FIELD_MATCH(adoi, DAL_PORT_A_K_MIBCLR_F_UPNUM_U64)) { dalAdoiGetActionUI64(adoi, &upIdx); } else { DBG_ERR("Invalid field %s !", field); } } DBG_ALZ("upIdx:%llu", upIdx); if (0 == upIdx) { hiPortMibCountClearAll(upIdx); } } done: return ret; } /**************************************************************************************************/ /* PUBLIC_FUNCTIONS */ /**************************************************************************************************/ int dalL2_portInit() { PFM_IF_FAIL_RET_VAL(dalHandlerReg(DAL_MOD_PORT, _dalL2PortHandle), ERR_INIT); return ERR_NO_ERROR; } int dalL2PortTimerStart() { static TIMER_ID portMibTimer; static TIMER_ID portStateTimer; struct timespec tm_mib = {.tv_sec = 5, .tv_nsec = 0}; struct timespec tm_state = {.tv_sec = 2, .tv_nsec = 0}; TIMER_ID_INIT(portMibTimer); portMibTimer = add_timer(PORT_MIB_TIMER_NAME, &tm_mib, portMibTimerHandle, NULL, 0, EXECUTE_FOREVER); if (!TIMER_ID_IS_VALID(portMibTimer)) { GR_PRINT_ERROR("Failed to add portMibTimer."); return ERR_INIT; } TIMER_ID_INIT(portStateTimer); portStateTimer = add_timer(PORT_STATE_TIMER_NAME, &tm_state, portStateTimerHandle, NULL, 0, EXECUTE_FOREVER); if (!TIMER_ID_IS_VALID(portStateTimer)) { GR_PRINT_ERROR("Failed to add portMibTimer."); return ERR_INIT; } return ERR_NO_ERROR; } 这两个代码有什么关系吗
07-30
在分析两个 C 语言代码文件之间是否存在关联时,可以从多个维度进行判断,包括功能、调用关系、代码结构以及是否涉及继承或模块化设计。 ### ### 功能关联 两个 C 文件之间可能存在功能上的关联,例如一个文件负责数据处理,另一个文件负责数据存储或网络通信。这种情况下,两个文件虽然在逻辑上独立,但共同完成某个整体任务。这种设计在模块化编程中非常常见,尤其在大型项目中,通常会将功能拆分为多个文件或模块,并通过静态库或动态库进行整合 [^2]。 ### ### 调用关系 C 语言中,函数调用是文件之间最直接的联系。如果一个 C 文件中定义的函数在另一个 C 文件中被调用,则这两个文件存在调用关系。这种关系通常通过头文件(.h)进行声明,并在源文件(.c)中实现和调用。例如: ```c // file1.h #ifndef FILE1_H #define FILE1_H void function_from_file1(); #endif // FILE1_H ``` ```c // file1.c #include "file1.h" #include <stdio.h> void function_from_file1() { printf("Function from file1\n"); } ``` ```c // file2.c #include "file1.h" int main() { function_from_file1(); // 调用来自 file1 的函数 return 0; } ``` 在此例中,`file2.c` 明确依赖于 `file1.c` 中定义的函数,二者存在直接调用关系 [^2]。 ### ### 代码结构与模块化 在大型项目中,C 语言通常采用模块化设计,即将功能相近的函数组织在同一个文件或模块中。模块之间可能通过函数指针、回调机制或接口函数进行通信。例如,一个模块提供事件注册接口,另一个模块注册回调函数,从而实现跨模块协作 。 ### ### 继承与强耦合 C 语言本身不支持面向对象的继承机制,但可以通过结构体嵌套和函数指针模拟类似行为。例如,一个结构体可以包含另一个结构体作为其第一个成员,从而实现“继承”效果。这种设计可能导致两个文件之间形成强耦合关系,特别是在多层结构嵌套的情况下,理解与维护成本较高 [^3]。 ```c // base.h typedef struct { int id; } Base; void base_init(Base* obj, int id); // derived.h #include "base.h" typedef struct { Base base; char name[32]; } Derived; void derived_init(Derived* obj, int id, const char* name); ``` 在上述代码中,`Derived` 结构体“继承”了 `Base` 的字段,这种设计模式在某些系统编程场景中被用于构建灵活的接口体系 [^3]。 ### ### 编译与链接层面的关联 即使两个 C 文件在源代码层面没有直接的函数调用关系,它们也可能通过共享的全局变量、宏定义或编译选项产生关联。此外,在链接阶段,如果两个文件都引用了同一个库或符号,则它们在最终可执行文件中是相关的 。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值