C语言提高之接口封装设计思想

断层思维

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

接口设计的设计思路

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#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)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#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)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#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)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#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)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#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)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#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;
}

Donate comment here