公司提供了一套接口供客户开发应用。这套接口的框架是用IPCRPC实现,严格意义上说这是伪IPCRPC,因为不涉及机器之间的通信,只是不同进程间的通信。
提供给客户的接口里面,其实只是通过socket发送信息到一个类似daemon的进程,具体的操作都是在deamon进程中,处理完后将结果返回给应用进程。mdnsResponder也是采用这样的思路。
在接口里面,将接口的函数名字和参数打包发给daemon进程,在daemon进程将一些相同名字的函数注册到一个哈希表中,当收到应用进程发来的函数名字后,直接查找哈希表,调用相应的函数。
基于上面这种想法,实现一个哈希表,以函数名为key,以函数作为value.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct _HashNode{
char *key;
void *value;
struct _HashNode *prev;
struct _HashNode *next;
}HashNode;
typedef struct _HashList{
HashNode *pListHead;//链表头
int elemNum;//链表中元素个数
}HashList;
typedef struct _HashTable{
HashList *pTable;
unsigned long tableSize;
}HashTable;//哈希表的每一项都是一个双链表
HashTable gHashTable;
typedef int (*Handle)();
void hash_init(HashTable *hashTable, unsigned long tableSize)
{
hashTable->pTable = (HashList *)malloc(tableSize * sizeof(HashList));
memset(hashTable->pTable, 0, tableSize * sizeof(HashList));
hashTable->tableSize = tableSize;
}
unsigned long hash_func(const char *key, unsigned long tableSize)
{
char *tmp = NULL;
unsigned long hashCode = 0;
for (tmp = key; *tmp != ' '; tmp++)
{
hashCode = hashCode * 31 + *tmp;
}
hashCode = hashCode & (tableSize - 1);
return hashCode;
}
void hash_add(HashTable *hashTable, const char *key, void *value)
{
unsigned long hashCode = hash_func(key, hashTable->tableSize);
HashNode *pNode = (HashNode *)malloc(sizeof(HashNode));
pNode->key = key;
pNode->value = value;
pNode->prev = pNode->next = NULL;
if (hashTable->pTable[hashCode].pListHead == NULL)
{
hashTable->pTable[hashCode].pListHead = pNode;
}
else
{
pNode->next = hashTable->pTable[hashCode].pListHead;
hashTable->pTable[hashCode].pListHead->prev = pNode;
hashTable->pTable[hashCode].pListHead = pNode;
}
hashTable->pTable[hashCode].elemNum++;
}
int hash_get(HashTable *hashTable, const char *key, void **value)
{
unsigned long hashCode = hash_func(key, hashTable->tableSize);
if (hashTable->pTable[hashCode].pListHead == NULL)
{
printf("key:%s NOT found
", key);
return 0;
}
else
{
HashNode *tmp = NULL;
for (tmp = hashTable->pTable[hashCode].pListHead; tmp; tmp = tmp->next)
{
if(!strncmp(tmp->key, key, strlen(key)))
{
if (value)
{
*value = tmp->value;
}
return 1;
}
}
}
printf("1key:%s NOT found
", key);
return 0;
}
int handle_fellow_open()
{
printf("fellow open!
");
}
int handle_fellow_close()
{
printf("fellow close!
");
}
int handle_fellow_play()
{
printf("fellow play!
");
}
void reg_handle_func(HashTable *hashTable, const char *key, Handle handle)
{
printf("reg %s, 0x%x
", key, (int)handle);
if (hash_get(hashTable, key, NULL))
{
printf("already exist
");
return;
}
hash_add(hashTable, key, handle);
}
#define REG_HANDLE(name)
do{reg_handle_func(&gHashTable, #name, handle_##name);}while(0)
void init_handle()
{
REG_HANDLE(fellow_open);
REG_HANDLE(fellow_close);
REG_HANDLE(fellow_play);
}
void main(void)
{
hash_init(&gHashTable, 1024);
init_handle();
Handle handle;
hash_get(&gHashTable, "fellow_play", (void **)&handle);
handle();
reg_handle_func(&gHashTable, "fellow_open", handle_fellow_open);
hash_get(&gHashTable, "fellow_close", (void **)&handle);
handle();
}
运行结果如下: