|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
1、日志库
在函数出错或是调用调试时记录日志,是软件开发中的重要部分,下面是一套打印日志的函数,可以做成动态库。
程序中存在着open()等文件操作函数,在win7 x64环境中运行不正常(日志文件不能正常生成);但业务逻辑可学习。
itcastlog.h
- #ifndef _ITCAST_LOG_H_
- #define _ITCAST_LOG_H_
- /*
- #define IC_NO_LOG_LEVEL 0
- #define IC_DEBUG_LEVEL 1
- #define IC_INFO_LEVEL 2
- #define IC_WARNING_LEVEL 3
- #define IC_ERROR_LEVEL 4;
- */
- /************************************************************************/
- /*
- 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 ITCAST_LOG(const char *file, int line, int level, int status, const char *fmt, ...);
- #endif
复制代码
itcastlog.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 "ItcastLog.h"
- #define ITCAST_DEBUG_FILE_ "socketclient.log"
- #define ITCAST_MAX_STRING_LEN 10240
- //Level类别
- #define IC_NO_LOG_LEVEL 0
- #define IC_DEBUG_LEVEL 1
- #define IC_INFO_LEVEL 2
- #define IC_WARNING_LEVEL 3
- #define IC_ERROR_LEVEL 4
- int LogLevel[5] = {IC_NO_LOG_LEVEL, IC_DEBUG_LEVEL, IC_INFO_LEVEL, IC_WARNING_LEVEL, IC_ERROR_LEVEL};
- //Level的名称
- char ICLevelName[5][10] = {"NOLOG", "DEBUG", "INFO", "WARNING", "ERROR"};
- static int ITCAST_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 ITCAST_Error_OpenFile(int* pf)
- {
- char fileName[1024];
-
- memset(fileName, 0, sizeof(fileName));
- #ifdef WIN32
- sprintf(fileName, "c:\\itcast\\%s",ITCAST_DEBUG_FILE_);
- printf("**x86** %s\n", fileName); // 说明我用的是x86环境
- #else
- //sprintf(fileName, "%s/log/%s", getenv("HOME"), ITCAST_DEBUG_FILE_);
- sprintf(fileName, "c:\\itcast\\%s",ITCAST_DEBUG_FILE_);
- printf("**x64** %s\n", fileName);
- #endif
-
- *pf = open(fileName, O_WRONLY|O_CREAT|O_APPEND, 0666);
- if(*pf < 0)
- {
- return -1;
- }
- return 0;
- }
- static void ITCAST_Error_Core(const char *file, int line, int level, int status, const char *fmt, va_list args)
- {
- char str[ITCAST_MAX_STRING_LEN];
- int strLen = 0;
- char tmpStr[64];
- int tmpStrLen = 0;
- int pf = 0;
-
- //初始化
- memset(str, 0, ITCAST_MAX_STRING_LEN);
- memset(tmpStr, 0, 64);
-
- //加入LOG时间
- tmpStrLen = ITCAST_Error_GetCurTime(tmpStr);
- tmpStrLen = sprintf(str, "[%s] ", tmpStr);
- strLen = tmpStrLen;
- //加入LOG等级
- tmpStrLen = sprintf(str+strLen, "[%s] ", ICLevelName[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(ITCAST_Error_OpenFile(&pf))
- {
- return ;
- }
-
- //写入LOG文件
- write(pf, str, strLen);
- //IC_Log_Error_WriteFile(str);
-
- //关闭文件
- close(pf);
-
- return ;
- }
- void ITCAST_LOG(const char *file, int line, int level, int status, const char *fmt, ...)
- {
- va_list args;
-
- //判断是否需要写LOG
- // if(level!=IC_DEBUG_LEVEL && level!=IC_INFO_LEVEL && level!=IC_WARNING_LEVEL && level!=IC_ERROR_LEVEL)
- if(level == IC_NO_LOG_LEVEL)
- {
- return ;
- }
-
- //调用核心的写LOG函数
- va_start(args, fmt);
- ITCAST_Error_Core(file, line, level, status, fmt, args);
- va_end(args);
- return ;
- }
复制代码
2、第二套api的实现
调用该api函数
- // 调用第二套api函数
- void main()
- {
- int ret = 0;
- void *handle = NULL;
- unsigned char buf[128];
- int buflen = 11; /*in*/
- unsigned char *out = NULL;
- int outlen = 0;
- strcpy(buf, "adddasdadddddddddasdada");
- // 客户端初始化
- ret = cltSocketInit2(&handle /*out*/);
- // 客户端发报文
- ret = cltSocketSend2(handle/*in*/, buf/*in*/, buflen/*in*/);
- // 客户端收报文
- ret = cltSocketRev2(handle/*in*/, &out, &outlen);
- ret = cltSocketRev2_Free(&out); //不但要把out所指向的内存空间释放,同样也把实参out赋成NULL,避免野指针
- //客户端释放资源
- if (handle != NULL)
- {
- cltSocketDestory2(&handle/*in*/);
- }
- system("pause");
- }
复制代码
第二套api函数的源码;该源码置于第一套之后,共同做成dll文件,用于别的函数调用。
- //------------------第二套api接口---Begin--------------------------------//
- //客户端初始化 获取handle上下
- __declspec(dllexport) //该语句的含义是下面的函数是向外抛出的函数
- int cltSocketInit2(void **handle /*out*/)
- {
- return cltSocketInit(handle);
- }
- //客户端发报文
- __declspec(dllexport)
- int cltSocketSend2(void *handle /*in*/, unsigned char *buf /*in*/, int buflen /*in*/)
- {
- return cltSocketSend(handle, buf, buflen);
- }
- //客户端收报文
- __declspec(dllexport)
- int cltSocketRev2(void *handle /*in*/, unsigned char **buf /*in*/, int *buflen /*in out*/)
- {
- int ret = 0;
- SCK_HANDLE *sh = NULL;
- unsigned char *tmp = NULL;
- if (handle == NULL || buf == NULL || buflen == NULL)
- {
- ret = -1;
- printf("func cltSocketRev2 error:%d", ret);
- return ret;
- }
- sh = (SCK_HANDLE *)handle;
- tmp = (char *)malloc(sh->buflen * sizeof(char));
- if (tmp == NULL)
- {
- ret = -1;
- printf("func cltSocketSend malloc error, buflen:%d", *buflen);
- return ret;
- }
- memcpy(tmp, sh->pbuf, sh->buflen);
- *buf = tmp;
- *buflen = sh->buflen;
- return ret;
- }
- __declspec(dllexport)
- int cltSocketRev2_Free(unsigned char **buf)
- {
- int ret = 0;
- if (buf == NULL)
- {
- ret = -1;
- printf("func cltSocketRev2_Free error:%d", ret);
- return ret;
- }
- free(*buf);
- *buf = NULL; // 释放的同时,也间接把实参修改啦
- return ret;
- }
- //客户端释放资源
- __declspec(dllexport)
- int cltSocketDestory2(void **handle/*in*/)
- {
- int ret = 0;
- SCK_HANDLE *sh = NULL;
- if (handle == NULL)
- {
- ret = -1;
- printf("func cltSocketDestory error:%d", ret);
- return ret;
- }
- sh = (SCK_HANDLE *) *handle;
- if (sh->pbuf != NULL)
- {
- free(sh->pbuf);
- }
- free(sh);
- *handle = NULL; // 间接修改实参的值,避免野指针
- return ret;
- }
- //------------------第二套api接口---End-----------------------------------//
复制代码
两套api函数的区别一个在主调函数中分配内存,一个在被调函数中分配内存。
另外:内存在哪里申请的的就要在哪里去释放,动态库里申请的内存就要调用动态库的函数去释放。
|
|