c语言 链表应用实例1

应用背景  canopen 协议栈中 ,对object dictionary 的回调函数, 通过指针函数数组的方式进行保存,

但这种保存方式有一个问题 就可能会浪费空间 。

所以这里采用链表方式存储回调函数 ,当然 必须额外空间存储链表操作的代码 。

工程是在Eclipse IDE for C/C++ Developers平台上 用c语言编写的 ,对于理解c语言指针应用有一定的帮助 。

原创文章,不得用于商业目的。 


/*

 * user.h
 *
 *  Created on: 2018年6月30日
 *      Author: gx fleetwgx [email protected]
 */


#ifndef USER_H_
#define USER_H_


#define bool unsigned char
#define null 0
#define true 1
#define false (!true)




#endif /* USER_H_ */


/*
 * linklist.h
 *
 *  Created on: 2018年6月30日
 *      Author: gx fleetwgx [email protected]
 */


#ifndef LINKLIST_H_
#define LINKLIST_H_


#include <stdio.h>
#include <stdlib.h>
#include "user.h"


#define LLIST_HEAD_INSERT 0x00
#define LLIST_TAIL_INSERT 0x01


typedef struct LListNode
{
    void*pElement;
    struct LListNode *pNext;
}LListNode_t;


typedef struct LListNode* PLListNode;


/*
typedef struct LListHead
{
unsigned char nodeNum;
struct LListNode firstNode;
}LListHead_t;
*/


typedef bool (*NodeElementCmpFun)(void *pElementa ,void *pElemntb);
typedef void (*printElementFun)(void *pElement);
extern void initLList( LListNode_t**pNode );
extern LListNode_t *createLList( LListNode_t*pHead );
extern void clearLList( LListNode_t*pHead );
extern bool isEmptyLList( LListNode_t*pHead );
extern void* getLListElement( LListNode_t**pHead , void* pElement ,NodeElementCmpFun elementCmpCallBack );
extern int insertLList( LListNode_t**pHead , unsigned char type , void * pElement );
extern int modifyLList( LListNode_t*pHead , unsigned int key );
extern void printLList( LListNode_t*pHead ,printElementFun printCallback);


#endif /* LINKLIST_H_ */



/*
 * linklist.c
 *
 *  Created on: 2018年6月30日
 *      Author: gx fleetwgx [email protected]
 */


#include "linklist.h"




void initLList( LListNode_t**pNode )
{
*pNode = null;
}


LListNode_t *createLList( LListNode_t*pHead )
{
    return null;
}
void clearLList( LListNode_t*pHead )
{


}
bool isEmptyLList( LListNode_t*pHead )
{
    if(pHead == null){
    return true;
    }else{
    return false;
    }
}


void* getLListElement( LListNode_t**pHead , void *pElement , NodeElementCmpFun elementCmpCallBack )
{
    //unsigned int i;
    LListNode_t*pNode = *pHead;
    if( (*pHead==null) ||(pElement== null)){
    return pNode;
    }
    while( pNode!=null ){
       if( ( pNode->pElement!=null )/*&&(pElement!=null)*/&&(true == elementCmpCallBack( pNode->pElement , pElement) ) ){
       printf(" getLListElement result is the element in this LList!\n");
           break;
       }else{
       pNode = pNode->pNext;
       }
    }
    return pNode;
}


int insertLList( LListNode_t **pHead , unsigned char type , void * pElement )
{
struct LListNode* pNewNode;
if(  ( pElement == null ) || (type > LLIST_TAIL_INSERT) ){
        return false;
    }
    if( *pHead == null ){
    pNewNode = malloc(sizeof(struct LListNode));
    if(pNewNode!=null){
    pNewNode->pElement = pElement;
    pNewNode->pNext = null;
    *pHead = pNewNode;
    }
    }
    else if( type == LLIST_HEAD_INSERT ){
        pNewNode = (struct LListNode*)malloc( sizeof(struct LListNode) );
        if(pNewNode!=null){
           pNewNode->pElement = pElement;
           pNewNode->pNext =  (*pHead)->pNext;
           (*pHead)->pNext = pNewNode;
        }
    }else {
            ;//
    }
return true;
}


int modifyLList( LListNode_t*pHead , unsigned int key )
{
    return 0;
}


void printLList( LListNode_t*pHead ,printElementFun printCallback)
{
LListNode_t *pNode;
if(pHead==null){
    printf("the input LList is a null list!\n");
    }else{
    pNode = pHead;
    printf("--------printLList------------\n");
    while(pNode!=null){
    printf("the current LListNode element is:\n");
    printCallback(pNode->pElement);
    pNode = pNode->pNext;
    printf("\n");
    }
    printf("------------end--------------\n");
    }

}


/*
 * odjacess.h
 *
 *  Created on: 2018年6月30日
 *      Author: gx fleetwgx [email protected]
 */


#ifndef ODJACESS_H_
#define ODJACESS_H_


#include <stdio.h>
#include <stdlib.h>
#include "user.h"
#include "linklist.h"
//#define null 0
#define OD_SUCCESSFUL              0x00000000
#define OD_READ_NOT_ALLOWED          0x06010001
#define OD_WRITE_NOT_ALLOWED         0x06010002
#define OD_NO_SUCH_OBJECT            0x06020000
#define OD_NOT_MAPPABLE              0x06040041
#define OD_LENGTH_DATA_INVALID       0x06070010
#define OD_NO_SUCH_SUBINDEX      0x06090011
#define OD_VALUE_TOO_LOW             0x06090031 /* Value range test result */
#define OD_VALUE_TOO_HIGH            0x06090032 /* Value range test result */
#define OD_CALLBACK_NOTSUPPORT       0x06090033 /* add by user*/
/* Others SDO abort codes
 */
#define SDOABT_TOGGLE_NOT_ALTERNED   0x05030000
#define SDOABT_TIMED_OUT             0x05040000
#define SDOABT_OUT_OF_MEMORY         0x05040005 /* Size data exceed SDO_MAX_LENGTH_TRANSFERT */
#define SDOABT_GENERAL_ERROR         0x08000000 /* Error size of SDO message */
#define SDOABT_LOCAL_CTRL_ERROR      0x08000021


typedef struct Co_Handle;
typedef struct Co_OdHandle;
typedef struct td_subindex
{
    unsigned char   bAccessType;
    unsigned char   bDataType; /* Defines of what datatype the entry is */
    unsigned char   size;      /* The size (in Byte) of the variable */
    void*           pObject;   /* This is the pointer of the Variable */
} subindex;


/** Struct for creating entries in the communictaion profile
 */
typedef struct td_indextable
{
    subindex*       pSubindex;   /* Pointer to the subindex */
    unsigned char   bSubCount;   /* the count of valid entries for this subindex
                         * This count here defines how many memory has been
                         * allocated. this memory does not have to be used.
                         */
    unsigned char   index;
} indextable;






typedef unsigned int ( *ODCallBack_t )( struct Co_Handle *pHandle , struct td_indextable* pIndexTable , unsigned char subIndex );


typedef const indextable * (*scanIndexOD_t)( struct Co_OdHandle* pHandle, unsigned short index, unsigned int * errorCode, void **Callback);




typedef struct Co_entrysubIndexCallBack
{
unsigned char subIndex;
ODCallBack_t  callBack;
}Co_entrysubIndexCallBack_t;




typedef struct Co_entryCallBacks
{
   unsigned short index ;
   unsigned char  subIndexNum;
   //struct Co_entrysubIndexCallBack* pCallBackList;//0x20//every index max 20 callback functions
#if 1
   struct LListNode* pCallBackList;//head
#else
   PLListNode pCallBackList;   //
#endif
}Co_entryCallBacks_t;




typedef struct Co_OdHandle
{
unsigned int  initFlag;
scanIndexOD_t scanIndexOD;
scanIndexOD_t getIndexCallbackList;
NodeElementCmpFun callbackCmp;
printElementFun   callBackPrint;
//struct Co_entryCallBacks*pOdEntryCallBacks;
}Co_OdHandle_t;




typedef struct Co_Handle
{
struct Co_OdHandle*pOdHandle;
}Co_Handle_t;




extern void Co_Init(struct Co_Handle* pHandle ,scanIndexOD_t scanIndeOdFun ,  unsigned char CallbackFunctionNum , unsigned short*pCallbackFunctionTables );
extern struct indextable * scanIndexODFun ( struct Co_OdHandle* pHandle, unsigned short index, unsigned int * errorCode, struct LListNode** pCallBackList /*ODCallBack_t **Callback*/);
//extern struct indextable * scanIndexODFun ( struct Co_OdHandle* pHandle, unsigned short index, unsigned int * errorCode, struct LListNode** pCallBackList /*ODCallBack_t **Callback*/)
//;


//extern struct indextable * scanIndexODFun (unsigned short index, unsigned int * errorCode, struct LListNode* pCallBackList /*ODCallBack_t **Callback*/ );

#endif /* ODJACESS_H_ */



/*
 * odjacess.c
 *
 *  Created on: 2018年6月30日
 *      Author: gx fleetwgx [email protected]
 */
#include "odjacess.h"
#include "linklist.h"
//struct Co_entryCallBacks OdEntryCallBacks[0x20];//0x20 *0x20 callback matrix
struct Co_entryCallBacks*pOdEntryCallBacks;


struct indextable * scanIndexODFun ( struct Co_OdHandle* pHandle, unsigned short index, unsigned int * errorCode, struct LListNode** pCallBackList /*ODCallBack_t **Callback*/)
{
unsigned int i;
printf(" objaccess -> call scanIndexODFun\n");
*errorCode = OD_CALLBACK_NOTSUPPORT;//
for(i = 0 ; i < 0x20 ; i++ ){
       //if(index == pHandle->pOdEntryCallBacks[i].index ){
if( index == pOdEntryCallBacks[i].index){
*pCallBackList = (struct LListNode*) (&(pOdEntryCallBacks[i].pCallBackList));
        *errorCode = OD_SUCCESSFUL;
       break;
       }
}
    return null;
}


bool SubIndexcallBackFunCmp( void*callBacka , void*callBackb )
{
   if( ((struct Co_entrysubIndexCallBack*)callBacka)->subIndex ==\
   ((struct Co_entrysubIndexCallBack*)callBackb)->subIndex ){
        return true;
   }else{
        return false;
   }
   //
}


void SubIndexcallBackFunPrint( void*pElement )
{
    if( pElement!=null ){
    printf("the subindex is : %d \n" , ( (struct Co_entrysubIndexCallBack *)pElement)->subIndex  );


    }else{
    printf("pElement is null\n");
    }
}


void SubIndexcallBackFunPrint2( struct Co_Handle* pHandle,  LListNode_t*pHead  )
{
LListNode_t*pNode;
pNode = pHead;
unsigned char subIndex;
while(pNode!=null){
if(pNode->pElement!=null){
  subIndex = ((struct Co_entrysubIndexCallBack*)(pNode->pElement))->subIndex;
      ((struct Co_entrysubIndexCallBack*)(pNode->pElement))->callBack(pHandle,null,subIndex);
}
pNode = pNode->pNext;
     }
}




//list tables
void Co_Init(struct Co_Handle* pHandle ,scanIndexOD_t scanIndeOdFun ,  unsigned char CallbackFunctionNum , unsigned short*pCallbackFunctionTables )
{
unsigned int i;
// unsigned char CallbackFunctionSize[][];
struct Co_entryCallBacks temp;//debug
pHandle->pOdHandle = malloc(sizeof(Co_OdHandle_t) );
    if( (pHandle->pOdHandle!=null) && (scanIndeOdFun!=null) ){
        //(*pHandle->pOdHandle).scanIndexOD = scanIndeOdFun;
        (*pHandle->pOdHandle).getIndexCallbackList = scanIndeOdFun;


    (*pHandle->pOdHandle).initFlag = 0x55AA; //
        (*pHandle->pOdHandle).callbackCmp   = SubIndexcallBackFunCmp;
        (*pHandle->pOdHandle).callBackPrint = SubIndexcallBackFunPrint;
    pOdEntryCallBacks = malloc(CallbackFunctionNum*sizeof(Co_entryCallBacks_t) );
    if( pOdEntryCallBacks !=null){
             for( i = 0 ; i < CallbackFunctionNum ; i++){
            pOdEntryCallBacks[i].index = pCallbackFunctionTables[i];
            pOdEntryCallBacks[i].subIndexNum = 0;
            initLList(&pOdEntryCallBacks[i].pCallBackList); //a simple method, consider *p as a normal variable,
            temp = pOdEntryCallBacks[i];
             }
    }




    /*
    pHandle->pOdHandle->pOdEntryCallBacks = malloc(CallbackFunctionNum*sizeof(Co_entryCallBacks_t) );
    if( pHandle->pOdHandle->pOdEntryCallBacks !=null){
             for( i = 0 ; i < CallbackFunctionNum ; i++){
            pHandle->pOdHandle->pOdEntryCallBacks[i].index = pCallbackFunctionTables[i];
             }
    }
    */
        //
    }else{
        (*pHandle->pOdHandle).scanIndexOD = null;
    (*pHandle->pOdHandle).initFlag = 0x0000; //
    }
    //




}
struct Co_OdHandle*  Co_getOdHandle(struct Co_Handle* pHandle)
{
if(pHandle!=null){
    return pHandle->pOdHandle;
}else{
return null;
}
}




indextable * scanIndexOD( struct Co_OdHandle* pOdHandle, unsigned short index, unsigned int * errorCode, ODCallBack_t **Callback )
{
if( ( pOdHandle!=null) && ( pOdHandle->scanIndexOD!=null ) ){
    return pOdHandle->scanIndexOD( pOdHandle , index , errorCode , Callback );
}else{
        return null;
}
}


indextable * getIndexCallbackList( struct Co_OdHandle* pOdHandle , unsigned short index , unsigned int * errorCode, struct LListNode  **pCallBackListHead )
{
if( ( pOdHandle!=null) && ( pOdHandle->getIndexCallbackList!=null ) ){
    return pOdHandle->getIndexCallbackList( pOdHandle , index , errorCode , pCallBackListHead );
}else{
        return null;
}
}


#if 1
bool getIndexCallBackListHead( struct Co_OdHandle* pOdHandle , unsigned short index , struct LListNode  **pCallBackListHead)//
#else
bool getIndexCallBackListHead( struct Co_OdHandle* pOdHandle , unsigned short index , PLListNode *pCallBackListHead)
#endif
{
unsigned int errCode;
getIndexCallbackList(pOdHandle , index , &errCode, pCallBackListHead);
if(errCode == OD_SUCCESSFUL)
return true;
else
    return false;
}


void printIndexCallBackList( struct Co_OdHandle *pOdHandle , LListNode_t**pHead)
{
if( (pOdHandle!=null)&&(pHead!=null) )
   printLList(*pHead , pOdHandle->callBackPrint );
}


struct Co_entrysubIndexCallBack * createSubIndexCallBackNode(unsigned char subIndex , ODCallBack_t callBack )
{
struct Co_entrysubIndexCallBack *pCallBackNodeElement = null;
pCallBackNodeElement = malloc( sizeof( struct Co_entrysubIndexCallBack ) );//
if(pCallBackNodeElement!=null){
   pCallBackNodeElement->callBack = callBack; //
   pCallBackNodeElement->subIndex = subIndex; //
   return pCallBackNodeElement;
}else{
       return null;
}
}


bool deleteSubIndexCallBackNode( struct Co_entrysubIndexCallBack * pNode )
{
if( pNode!=null ){
free(pNode);
return true;
}else{
return false;
}
}


bool setSubIndexCallBackNode( struct Co_entrysubIndexCallBack *pNode , ODCallBack_t callBack )//
{
if(pNode!=null){
    pNode->callBack = callBack;
    return true;
}else{
return false;
}
}






struct Co_entrysubIndexCallBack * getSubIndexCallBackNode( struct Co_OdHandle *pOdHandle , LListNode_t**pHead , unsigned char subIndex)
{
struct LListNode *pNode;
struct Co_entrysubIndexCallBack CallBackNodeElement;
CallBackNodeElement.subIndex =  subIndex;
pNode = getLListElement( pHead , &CallBackNodeElement , pOdHandle->callbackCmp );
if(pNode!=null){
        return (struct Co_entrysubIndexCallBack *)pNode->pElement;
}
    return null;
}


bool addSubIndexCallBackNodeToIndexCallBackList(LListNode_t**pHead,struct Co_entrysubIndexCallBack *pCallBackNodeElement)
{
if( (pHead != null ) &&( pCallBackNodeElement != null ) ){
    return insertLList( pHead ,  LLIST_HEAD_INSERT , pCallBackNodeElement) ;
}else{
return false;
}
}


bool removeSubIndexCallBackNodeToIndexCallBackList(LListNode_t*pHead ,unsigned char subIndex)
{
    return false;
}






unsigned int RegisterODCallBack( struct Co_Handle *pHandle , unsigned short index ,unsigned char subIndex ,   ODCallBack_t callBack)//
{
unsigned int errCode;
struct Co_OdHandle *pOdHandle = pHandle->pOdHandle;
#if 1
struct LListNode  **pCallBackListHead = null;
#else
PLListNode *pCallBackListHead = null;
#endif
struct Co_entrysubIndexCallBack *pCallBackNodeElement = null;


if( true == getIndexCallBackListHead (pOdHandle , index  , &pCallBackListHead) ){
/*why here use &pCallBackListHead?
* int a; fun(int*a)  fun(&a);
* int**a; fun(int**a) fun(&a);
*
* */
    //


pCallBackNodeElement = getSubIndexCallBackNode(pOdHandle,pCallBackListHead,subIndex);
if( pCallBackNodeElement!=null ){
setSubIndexCallBackNode( pCallBackNodeElement , callBack);
}else{
    pCallBackNodeElement = createSubIndexCallBackNode( subIndex , callBack );//
    errCode = OD_SUCCESSFUL;
            if( (pCallBackNodeElement!=null)&&
            (false == addSubIndexCallBackNodeToIndexCallBackList( pCallBackListHead ,pCallBackNodeElement )) ){
            deleteSubIndexCallBackNode(pCallBackNodeElement);
            errCode = ~OD_SUCCESSFUL;
            }
            printIndexCallBackList(pOdHandle,pCallBackListHead);
}
    }
return errCode;
}




/*
 ============================================================================
 Name        : test2.c
 Author      : guixin fleetwgx [email protected]
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================
 */


#include <stdio.h>
#include <stdlib.h>
#include "odjacess.h"
static unsigned int OnCob_Id_SyncUpdate(struct Co_Handle *pHandle , struct td_indextable* pIndexTable , unsigned char subIndex )
{
printf(" test2 -> call OnCob_Id_SyncUpdate\n,subindex = %x\n",subIndex);
startSync(pHandle);
    return 0;
}


void startSync( struct Co_Handle *pHandle)
{
printf(" test2 -> call startSync \n");
RegisterODCallBack( pHandle , 0x1005 ,0x0 ,  OnCob_Id_SyncUpdate );//
RegisterODCallBack( pHandle , 0x1006 ,0x0 ,  OnCob_Id_SyncUpdate );//
RegisterODCallBack( pHandle , 0x1005 ,0x0 ,  OnCob_Id_SyncUpdate );//only for debug
RegisterODCallBack( pHandle , 0x1006 ,0x0 ,  OnCob_Id_SyncUpdate );//only for debug
RegisterODCallBack( pHandle , 0x1005 ,0x1 ,  OnCob_Id_SyncUpdate );//only for debug
RegisterODCallBack( pHandle , 0x1005 ,0x2 ,  OnCob_Id_SyncUpdate );//only for debug
RegisterODCallBack( pHandle , 0x1005 ,0x3 ,  OnCob_Id_SyncUpdate );//only for debug
RegisterODCallBack( pHandle , 0x1005 ,0x4 ,  OnCob_Id_SyncUpdate );//only for debug
    //




}




struct Co_Handle coHandle;


unsigned short oDCallBackMatrixs[]=
{
    0x1005,
    0x1006,
    0x1007,
    0x1008,
    0x1009,
    0x100a
};


int main(void) {
puts("!!!Hello World!!!18-7-7\n"); /* prints !!!Hello World!!! */
Co_Init( &coHandle , scanIndexODFun , sizeof(oDCallBackMatrixs)/2 , &oDCallBackMatrixs ); //
startSync(&coHandle); //
struct LListNode  **pCallBackListHead = null;
unsigned int errCode;
struct Co_OdHandle* pOdHandle;
pOdHandle = Co_getOdHandle();
puts("debug continue....\n");
if( ( pOdHandle!=null)/* && ( coHandle.pOdHandle->scanIndexOD!=null )*/ ){
if(true == getIndexCallBackListHead( pOdHandle , 0x1005  , &pCallBackListHead)){
SubIndexcallBackFunPrint2( &coHandle,  *pCallBackListHead  );
}
if(true == getIndexCallBackListHead( pOdHandle , 0x1006  , &pCallBackListHead)){
SubIndexcallBackFunPrint2( &coHandle,  *pCallBackListHead  );
}
}
return EXIT_SUCCESS;
}


猜你喜欢

转载自blog.csdn.net/fleetwgx/article/details/80951479