断层思维

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

接口设计的设计思路

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]\n", 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;
}

深入理解C语言-接口封装设计思想的更多相关文章

  1. MapReduce原理与设计思想

    简单解释 MapReduce 算法 一个有趣的例子 你想数出一摞牌中有多少张黑桃.直观方式是一张一张检查并且数出有多少张是黑桃? MapReduce方法则是: 给在座的所有玩家中分配这摞牌 让每个玩家 ...

  2. 大数据 --> MapReduce原理与设计思想

    MapReduce原理与设计思想 简单解释 MapReduce 算法 一个有趣的例子:你想数出一摞牌中有多少张黑桃.直观方式是一张一张检查并且数出有多少张是黑桃? MapReduce方法则是: 给在座 ...

  3. php命名空间的设计思想和缺点

    相比C#等语言,你可以在PHP函数里面随意定义变量并赋值,而不用担心覆盖了全局变量,或者类变量:你也可以随意的定义类变量,而不用担心会和函数名冲突,因为变量前面都有个$. php的命名空间和全局变量. ...

  4. 转:MapReduce原理与设计思想

    转自:http://www.cnblogs.com/wuyudong/p/mapreduce-principle.html 简单解释 MapReduce 算法 一个有趣的例子 你想数出一摞牌中有多少张 ...

  5. Day1:了解APICloud平台、理解APICloud应用设计思想、掌握平台使用流程。学习如何对一款APP进行需求分析、功能分解和架构设计等编码之前重要的准备工作

    学习目标 总体上了解一下APICloud平台,重点介绍相关的学习资源,入门资料,常见的FAQ等 明确我们这七天要开发一个什么样的APP,明确功能需求,跟上每天的课程节奏,可以课前预习 梳理出对于一款A ...

  6. 透彻理解Spring事务设计思想之手写实现

    前言 事务,是描述一组操作的抽象,比如对数据库的一组操作,要么全部成功,要么全部失败.事务具有4个特性:Atomicity(原子性),Consistency(一致性),Isolation(隔离性),D ...

  7. 《深入理解Android内核设计思想》

    <深入理解Android内核设计思想> 基本信息 作者: 林学森 出版社:人民邮电出版社 ISBN:9787115348418 上架时间:2014-4-25 出版日期:2014 年5月 开 ...

  8. 透彻理解Spring事务设计思想之手写实现(山东数漫江湖)

    前言 事务,是描述一组操作的抽象,比如对数据库的一组操作,要么全部成功,要么全部失败.事务具有4个特性:Atomicity(原子性),Consistency(一致性),Isolation(隔离性),D ...

  9. 聊聊高并发(三十八)解析java.util.concurrent各个组件(十四) 理解Executor接口的设计

    JUC包中除了一系列的同步类之外,就是Executor运行框架相关的类.对于一个运行框架来说,能够分为两部分 1. 任务的提交 2. 任务的运行. 这是一个生产者消费者模式,提交任务的操作是生产者,运 ...

随机推荐

  1. 压测工具ab的简单使用

    apache benchmark(ab)是一种常见的压测工具,不仅可以对apache进行压测,也可以对nginx,tomcat,IIS等进行压测 安装 如果安装了apache,那么ab已经自带了,不需 ...

  2. js+下载文件夹

    一.此方法火狐有些版本是不支持的 window.location.href = 'https://*****.oss-cn-**.aliyuncs.com/*********'; 二.为了解决火狐有些 ...

  3. (九)文档和视图,Invalidate,数据库编程

    一.文档视图结构 文档类(CDocument):存储加载(读写)数据视图类(CView):显示和修改数据 1)单文档 a)文档模板:把框架窗口.文档.视图关联在一起b)文档类(CDocument): ...

  4. Python 通过文件名批量移动文件

    Python 通过文件名批量移动文件 https://stackoverflow.com/questions/28913088/moving-files-with-wildcards-in-pytho ...

  5. deepin grub2017年11月13日折腾记录

    http://blog.csdn.net/atbird0321/article/details/78158194 https://bbs.deepin.org/forum.php?mod=viewth ...

  6. QAbstractTableModel中的data()到底执行几遍???

    发现问题的过程  1.一个普通的继承 QAbstractTableModel 的类 class CurrencyModel : public QAbstractTableModel { public: ...

  7. centos6安装sshpass

    跳转机需要装这个 #!/bin/bash yum -y install gcc-c++ openssh-clients curl -o sshpass.tar.gz http://sourceforg ...

  8. 复杂sql语句集锦

    本文主要讲一下笔者在工作中遇到的一些逻辑比较复杂的sql语句,下面是具体写法: SELECT IF ( LOCATE() , NULL, SUBSTRING( link, LOCATE() , IF ...

  9. [java]将秒数转化为“天时分秒”的格式(转贴+修改)

    public class Time { // format seconds to day hour minute seconds style // Exmplae 5000s will be form ...

  10. 2.基于AOP自定义注解Annotation的实现

    上一篇中分析了AOP的实现原理, 总结为: 判断对象是否需要被代理?@Aspect注解的实现是根据切入点表达式 代理之后需要做什么,就是那些通知,本质上是实现了MethodInterceptor的拦截 ...