断层思维

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

接口设计的设计思路

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. docker管理

    查看容器名 [root@docker ~]# docker inspect -f "{{.Name}}" a2f /u1 停止/启动终止状态的容器 [root@docker ~]# ...

  2. PHP mysqli_free_result() 函数

    mysqli_free_result() 函数释放结果内存. <?php // 假定数据库用户名:root,密码:123456,数据库:RUNOOB $con=mysqli_connect(&q ...

  3. CKEditor从word粘贴问题

    最近公司做项目需要实现一个功能,在网页富文本编辑器中实现粘贴Word图文的功能. 我们在网站中使用的Web编辑器比较多,都是根据用户需求来选择的.目前还没有固定哪一个编辑器 有时候用的是UEditor ...

  4. window上git bash运行错误记录

    错误现象:每次启动git bash报出如下错误gitbash  0 [main] bash 11928 fork: child -1 - CreateProcessW failed for 'D:\P ...

  5. Selenium报错:StaleElementReferenceException

    一个学生在操作页面跳转时遇到一个Selenium报错, 如下图所示: StaleElementReferenceException: Message: stale element reference: ...

  6. CodeForces 755D PolandBall and Polygon ——(xjbg)

    每次连线,起点和终点之间,每一个被点亮的点,这些点都能连出去两条线,因此可以增加的块数+2(1这个点除外,因为只有连出的点没有连进的点),计算起点和终点之间有几个点被点亮即可,然后1这个点特判一下.感 ...

  7. 安装完Pycharm,启动时碰到"failed to load jvm dll"的解决方案

    今天安装完系统,配置pycharm的环境的时候,启动pycharm时,碰到"failed to load jvm dll"的错误, 下面给出其解决方案: 安装Microsoft V ...

  8. Linux设备驱动程序 之 open和release

    open方法 open方法提供给驱动程序以初始化的能力,在大部分驱动程序汇总,open应该完成以下工作: 1. 检查特定设备的错误,如设备为准备就绪或者硬件问题: 2. 如果设备是首次打开,则对其进行 ...

  9. 前端知识扫盲-VUE知识篇一(VUE核心知识)

    最近对整个前端的知识做了一次复盘,总结了一些知识点,分享给大家有助于加深印象. 想要更加理解透彻的同学,还需要大家自己去查阅资料或者翻看源码.后面会陆续的更新一些相关注知识点的文章. 文章只提出问题, ...

  10. BrowserUtils

    import android.content.Context; import android.content.Intent; import android.net.Uri; public class ...