zoukankan      html  css  js  c++  java
  • 深入理解C语言-接口封装设计思想

    断层思维

    在设计时候,不需要知道实现,只需要知道如何使用

    接口设计的设计思路

    Sckclient客户端api模型
    第一套API
    (*.h)

    #ifndef _SCK_CLINT_H_
    #define _SCK_CLINT_H_
    
    #ifdef  __cplusplus
    extern "C" {
    #endif
    
    //函数声明
    // 1、客户端环境初始化
    int sckClient_init(void **handle); 
    // 2、客户端发送报文
    int sckClient_send(void *handle, unsigned char *data, int datalen);
    // 3、客户端端接受报文
    int sckClient_rev(void *handle, unsigned char *out, int *outlen); 
    // 4、客户端环境释放 
    int sckClient_destroy(void *handle);
    
    #ifdef  __cplusplus
    }
    #endif
    #endif
    

    (*.c)

    #include "stdlib.h"
    #include "stdio.h"
    #include "string.h"
    
    typedef struct _SCK_HANDLE {
    	char           version[16];
    	char           serverip[16];
    	int            serverport;
    	unsigned char *buf ;
    	int            buflen;
    }SCK_HANDLE;
    
    //客户端初始化 获取handle上下
    __declspec(dllexport) 
    int cltSocketInit(void **handle /*out*/)
    {
    	int ret = 0;
    	SCK_HANDLE *sh = NULL;
    	sh = (SCK_HANDLE *)malloc(sizeof(SCK_HANDLE));
    	if (sh == NULL)
    	{
    		ret = -1;
    		printf("func cltSocketInit() err: %d, malloc err....", ret);
    		return ret;
    	}
    	memset(sh, 0, sizeof(SCK_HANDLE));
    	strcpy(sh->serverip, "192.168.0.128");
    	sh->serverport= 88;
    
    	*handle = sh;
    	return ret;
    }
    
    //客户端发报文
    __declspec(dllexport) 
    int cltSocketSend(void *handle /*in*/, unsigned char *buf /*in*/,  int buflen /*in*/)
    {
    	int		ret = 0;
    	SCK_HANDLE *sh = NULL; 
    	
    	if (handle==NULL || buf==NULL)
    	{
    		ret = -1;
    		printf("func cltSocketSend() err: %d, (handle==NULL || buf==NULL)", ret);
    		return ret;
    	}
    	sh = (SCK_HANDLE *)handle ;
    	sh->buf = (char *)malloc(buflen);
    	if (sh->buf == NULL)
    	{
    		ret = -2;
    		printf("func cltSocketSend() err: %d, (buflen:%d)", ret, buflen);
    		return ret;
    	}
    	memcpy(sh->buf, buf, buflen);
    	sh->buflen = buflen;
    
    	return ret;
    }
    
    
    //客户端收报文
    __declspec(dllexport) 
    int cltSocketRev(void *handle /*in*/, unsigned char *buf /*in*/, int *buflen /*in out*/)
    {
    	int  ret = 0;
    	SCK_HANDLE *sh = NULL; 
    
    	if (handle==NULL || buf==NULL || buflen==NULL)
    	{
    		ret = -1;
    		printf("func cltSocketSend() err: %d, ((handle==NULL || buf==NULL || buflen==NULL))", ret);
    		return ret;
    	}
    
    	sh = (SCK_HANDLE *)handle;
    
    	memcpy(buf, sh->buf, sh->buflen);
    	*buflen  = sh->buflen;
    
    	if (sh->buf != NULL)
    	{
    		free(sh->buf);
    		sh->buf = NULL; //把状态回到原始
    		sh->buflen = 0;
    	}
    	return ret;
    }
    
    
    //客户端释放资源
    __declspec(dllexport) 
    int cltSocketDestory(void *handle/*in*/)
    {
    	int  ret = 0;
    	SCK_HANDLE *sh = NULL; 
    
    	if (handle==NULL )
    	{
    		ret = -1;
    		printf("func cltSocketSend() err: %d, ((handle==NULL )", ret);
    		return ret;
    	}
    
    	sh = (SCK_HANDLE *)handle;
    	
    	if (sh->buf != NULL)
    	{
    		free(sh->buf);
    		sh->buf = NULL;
    		sh->buflen = 0;
    	}
    	free(sh);
    
    	return ret;
    }
    

    第二套API
    (*.h)

    #ifndef _SCK_CLINT02_H_
    #define _SCK_CLINT02_H_
    
    #ifdef  __cplusplus
    extern "C" {
    #endif
    
    //函数声明
    // 1、客户端环境初始化
    int sckClient_init2(void **handle); 
    // 2、客户端发送报文
    int sckClient_send2(void *handle, unsigned char *data, int datalen);
    // 3、客户端端接受报文
    int sckClient_rev2(void *handle, unsigned char **out, int *outlen); 
    int sckClient_rev2_Free(void **p); 
    // 4、客户端环境释放 
    int sckClient_destroy2(void **handle);
    
    #ifdef  __cplusplus
    }
    #endif
    
    #endif
    

    (*.c)

    #include "stdlib.h"
    #include "stdio.h"
    #include "string.h"
    
    
    typedef struct _SCK_HANDLE {
    	char           version[16];
    	char           serverip[16];
    	int            serverport;
    	unsigned char *buf ;
    	int            buflen;
    }SCK_HANDLE;
    
    //客户端环境初始化
    __declspec(dllexport)
    int cltSocketInit2(void **handle)
    {
    	return cltSocketInit(handle /*out*/);
    }
    
    //客户端发报文
    __declspec(dllexport)
    int cltSocketSend2(void *handle, unsigned char *buf,  int buflen)
    {
    	return cltSocketSend(handle /*in*/, buf /*in*/, buflen /*in*/);
    }
    //客户端收报文
    __declspec(dllexport)
    int cltSocketRev2(void *handle, unsigned char **buf, int *buflen)
    {
    	int  ret = 0;
    	SCK_HANDLE *sh = NULL; 
    
    	if (handle==NULL || buf==NULL || buflen==NULL)
    	{
    		ret = -1;
    		ITCAST_LOG(__FILE__, __LINE__, LogLevel[4], ret, "func cltSocketRev2() err: %d,  (handle==NULL || buf==NULL || buflen==NULL)", ret);
    		return ret;
    	}
    
    	sh = (SCK_HANDLE *)handle;
    
    	*buf = (char *)malloc( sh->buflen);
    
    	memcpy(*buf, sh->buf, sh->buflen);
    	*buflen  = sh->buflen;
    	return ret;
    }
    
    __declspec(dllexport)
    int cltSocketRev2_Free(unsigned char **buf)
    {
    	if (buf == NULL)
    	{
    		return -1;
    	}
    	free(*buf);
    	*buf = NULL;
    	return 0;
    }
    //客户端释放资源
    __declspec(dllexport)
    int cltSocketDestory2(void **handle)
    {
    	int  ret = 0;
    	SCK_HANDLE *sh = NULL; 
    	
    
    	if (handle==NULL )
    	{
    		ret = -1;
    		ITCAST_LOG(__FILE__, __LINE__, LogLevel[4], ret, "func cltSocketSend() err: %d, ((handle==NULL )", ret);
    		return ret;
    	}
    
    	sh = (SCK_HANDLE *)*handle;
    
    	if (sh->buf != NULL)
    	{
    		free(sh->buf);
    		sh->buf = NULL;
    		sh->buflen = 0;
    	}
    	free(sh);
    	*handle = NULL; //把实参赋值null
    
    	return ret;
    }
    

    日志打印

    (*.h)

    #ifndef __LOG_H_
    #define __LOG_H_
    /***********************************************************************
    const char *file:文件名称
    int line:文件行号
    int level:错误级别
    0 -- 没有日志
    1 -- debug级别
    2 -- info级别
    3 -- warning级别
    4 -- err级别
    int status:错误码
    const char *fmt:可变参数
    ***********************************************************************/
    //实际使用的Level
    extern int  LogLevel[5];
    void LOG(const char *file, int line, int level, int status, const char *fmt, ...);
    #endif
    

    (*.c)

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <stdarg.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    #include "Log.h"
    
    #define DEBUG_FILE_	"error.log"
    #define MAX_STRING_LEN 		10240
    //日志输出目录
    #define FILE_SPACE "c:/log/%s"
    
    //Level类别
    #define NO_LOG_LEVEL	0
    #define DEBUG_LEVEL		1
    #define INFO_LEVEL		2
    #define WARNING_LEVEL	3
    #define ERROR_LEVEL		4
    
    //日志等级
    int  LogLevel[5] = { NO_LOG_LEVEL, DEBUG_LEVEL, INFO_LEVEL, WARNING_LEVEL, ERROR_LEVEL };
    
    //Level的名称
    char LevelName[5][10] = { "NOLOG", "DEBUG", "INFO", "WARNING", "ERROR" };
    
    static int Error_GetCurTime(char* strTime)
    {
    	struct tm*		tmTime = NULL;
    	size_t			timeLen = 0;
    	time_t			tTime = 0;
    
    	tTime = time(NULL);
    	tmTime = localtime(&tTime);
    	//timeLen = strftime(strTime, 33, "%Y(Y)%m(M)%d(D)%H(H)%M(M)%S(S)", tmTime);
    	timeLen = strftime(strTime, 33, "%Y.%m.%d %H:%M:%S", tmTime);
    
    	return timeLen;
    }
    
    static int Error_OpenFile(int* pf)
    {
    	char	fileName[1024];
    
    	memset(fileName, 0, sizeof(fileName));
    #ifdef WIN32
    	sprintf(fileName, FILE_SPACE, DEBUG_FILE_);
    #else
    	sprintf(fileName, FILE_SPACE, DEBUG_FILE_);
    	//sprintf(fileName, "%s/log/%s", getenv("HOME"), DEBUG_FILE_);
    #endif
    
    	*pf = open(fileName, O_WRONLY | O_CREAT | O_APPEND, 0666);
    	if (*pf < 0)
    	{
    		return -1;
    	}
    
    	return 0;
    }
    
    static void Error_Core(const char *file, int line, int level, int status, const char *fmt, va_list args)
    {
    	char str[MAX_STRING_LEN];
    	int	 strLen = 0;
    	char tmpStr[64];
    	int	 tmpStrLen = 0;
    	int  pf = 0;
    
    	//初始化
    	memset(str, 0, MAX_STRING_LEN);
    	memset(tmpStr, 0, 64);
    
    	//加入LOG时间
    	tmpStrLen = Error_GetCurTime(tmpStr);
    	tmpStrLen = sprintf(str, "[%s] ", tmpStr);
    	strLen = tmpStrLen;
    
    	//加入LOG等级
    	tmpStrLen = sprintf(str + strLen, "[%s] ", LevelName[level]);
    	strLen += tmpStrLen;
    
    	//加入LOG状态
    	if (status != 0)
    	{
    		tmpStrLen = sprintf(str + strLen, "[ERRNO is %d] ", status);
    	}
    	else
    	{
    		tmpStrLen = sprintf(str + strLen, "[SUCCESS] ");
    	}
    	strLen += tmpStrLen;
    
    	//加入LOG信息
    	tmpStrLen = vsprintf(str + strLen, fmt, args);
    	strLen += tmpStrLen;
    
    	//加入LOG发生文件
    	tmpStrLen = sprintf(str + strLen, " [%s]", file);
    	strLen += tmpStrLen;
    
    	//加入LOG发生行数
    	tmpStrLen = sprintf(str + strLen, " [%d]
    ", line);
    	strLen += tmpStrLen;
    
    	//打开LOG文件
    	if (Error_OpenFile(&pf))
    	{
    		return;
    	}
    
    	//写入LOG文件
    	write(pf, str, strLen);
    	//Log_Error_WriteFile(str);
    
    	//关闭文件
    	close(pf);
    
    	return;
    }
    
    
    void LOG(const char *file, int line, int level, int status, const char *fmt, ...)
    {
    	va_list args;
    
    	//判断是否需要写LOG
    	//	if(level!=DEBUG_LEVEL && level!=INFO_LEVEL && level!=WARNING_LEVEL && level!=ERROR_LEVEL)
    	if (level == NO_LOG_LEVEL)
    	{
    		return;
    	}
    
    	//调用核心的写LOG函数
    	va_start(args, fmt);
    	Error_Core(file, line, level, status, fmt, args);
    	va_end(args);
    
    	return;
    }
    
  • 相关阅读:
    LeetCode题解之Flipping an Image
    LeetCode 之Find Minimum in Rotated Sorted Array
    LeetCode题解Transpose Matrix
    LeetCode 题解之Minimum Index Sum of Two Lists
    LeetCode题解之Intersection of Two Linked Lists
    LeetCode 题解之Add Two Numbers II
    LeetCode题解之Add two numbers
    href="#"与href="javascript:void(0)"的区别
    有关ie9 以下不支持placeholder属性以及获得焦点placeholder的移除
    ie7下属性书写不规范造成的easyui 弹窗布局紊乱
  • 原文地址:https://www.cnblogs.com/cj5785/p/10664766.html
Copyright © 2011-2022 走看看