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;
    }
    
  • 相关阅读:
    Ubuntu将Python3软连接到Python
    装有Ubuntu的硬盘插入到电脑中无法进入
    如何更改鼠标右键新建内容
    HDU 1113 Word Amalgamation
    暴力题,速算24点
    网络营销整合
    灰色预测代码
    灾情巡视C语言代码
    灰色关联度Matlab代码
    BP神经网络代码
  • 原文地址:https://www.cnblogs.com/cj5785/p/10664767.html
Copyright © 2011-2022 走看看