添加代码与预编译指令与上一篇使用 Visual Studio 编译 wget 为可执行文件一致,区别在于这回建的是静态库工程(编译为动态库过程类似:))

从wget的main函数开始读下来,发现问题不少,程序可能基于效率或者编码方便的因素,大量使用静态变量,导致在将其修改为静态库之后存在潜在危险。

需要修改的部分如下:

1、main.c文件,no_prefix函数:

static char *
no_prefix (const char *s)
{
static char buffer[1024];
static char *p = buffer;
...
}

由于原程序使用指针p来指向尚未处理的数据,no_prefix函数调用一次p指针向后移动一段距离,直到buffer的末尾。

因为原有wget程序一次运行完成之后即退出,这段代码不会出问题,但在做为函数调用进行多次下载的时候,指针p没有移动到buffer的开头,就导致了缓冲区溢出问题。

只需在一次下载结束之后对其设置重置指针p的标志即可在下次执行下载任务开始前对指针p进行归位处理。

在no_prefix函数变量定义之后添加如下代码:

View Code

if (g_iIsClearBufferPointer == 1) //g_iIsClearBufferPointer为全局变量作为Flag
{
g_iIsClearBufferPointer = 0;
p = buffer;
}

2、添加回调函数及其参数定义

View Code

typedef enum{
Loading,
Complete,
Fail = -1
} DownloadInfoType;

typedef struct DownloadInfo_tag
{
float Percent;
char *pInfoStr;
void *pTag;
DownloadInfoType InfoType;
} DownloadInfo;

typedef void (* DOWNLOAD_CALLBACK)(DownloadInfo);
DOWNLOAD_CALLBACK g_download_process_callback = NULL;

3、外部调用下载所用函数:

View Code

//************************************
// Method: downloadFile
// FullName: downloadFile
// Access: public
// Returns: void
// Qualifier: 下载所用函数
// Parameter: char * pCmdStr:下载参数字符串,与wget命令行下载方式相同
// Parameter: DOWNLOAD_CALLBACK callbackFun:传入的回调函数指针
//************************************
void downloadFile(char *pCmdStr, DOWNLOAD_CALLBACK callbackFun)
{
char **cmd;
int iItemNum = 0;
int i;
g_download_process_callback = callbackFun;
cmd = (char**) malloc(sizeof(char*) * MAX_CMD_NUM);
for (i = 0; i < MAX_CMD_NUM; i++)
{
cmd[i] = ( char* ) malloc(sizeof(char) * MAX_PATH);
ZeroMemory(cmd[i], MAX_PATH);
}
divideCmdString(pCmdStr, cmd, MAX_CMD_NUM, &iItemNum);

wget_main(iItemNum, cmd);  //原有wget的main函数

for (i = 0; i < MAX_CMD_NUM; i++)
{
free(cmd[i]);
cmd[i] = NULL;
}
free(cmd);
cmd = NULL;
}

4、模拟系统分割参数字符串供wget的原有main函数使用

View Code

//************************************
// Method: divideCmdString
// FullName: divideCmdString
// Access: public
// Returns: void
// Qualifier:
// Parameter: char * pCmdStr:输入参数串
// Parameter: char * * pItems:输出分割好的参数
// Parameter: int iMaxItemNum:最大参数数目
// Parameter: int * pIItemNum:分割得到的参数数目
//************************************
void divideCmdString(char *pCmdStr, char **pItems, int iMaxItemNum, int *pIItemNum)
{
if (pCmdStr != NULL && pItems != NULL && pIItemNum != NULL)
{
int iCmdLen = strlen(pCmdStr);
int iCounter = 0;
int iInnerCounter = 0;
int i;
for (i = 0; i < iCmdLen; i++)
{
if (*(pCmdStr + i) == ' ') //是空格
{
if (iInnerCounter > 0)
{
pItems[iCounter][iInnerCounter] = '\0';
iInnerCounter = 0;
iCounter++;
if (iCounter >= iMaxItemNum)
{
*pIItemNum = --iCounter;
return;
}
}
}
else
{
pItems[iCounter][iInnerCounter] = *(pCmdStr + i);
iInnerCounter++;
}
}
pItems[iCounter][iInnerCounter] = '\0';
if (iInnerCounter == 0)
{
*pIItemNum = iCounter;
}
else
{
*pIItemNum = ++iCounter;
}

}
}

5、wget的main函数

第一个步骤是重置会引发错误的静态变量

View Code

g_iIsClearBufferPointer = 1; //清除no_prefix函数中静态变量指针
optind = 1; //清除getopt.c文件中的同名变量
total_downloaded_bytes = 0; //清除总下载量

第二个步骤是在函数中if (opt.recursive && opt.spider)的判断之后添加进度提示

View Code

/* Print broken links. */
if (opt.recursive && opt.spider)
{
print_broken_links();
}
//进度提示,此处为下载失败消息
if (total_downloaded_bytes == 0)
{
DownloadInfo info;
ZeroMemory(&info, sizeof(DownloadInfo));
info.InfoType = Fail;
g_download_process_callback(info);
}
/* Print the downloaded sum. */

6、在ftp.c的ftp_retrieve_list函数中添加下载进度提示

View Code

if (file_exists_p (con->target))
{
int iLen = strlen(con->target);
char *pSubStr = ".listing";
int iSubStrLen = strlen(pSubStr);
//避免在检测listing文件时错误发送complete消息 //linsy
if (strcmp(con->target + (iLen - iSubStrLen), pSubStr) != 0)
{
DownloadInfo info;
info.InfoType = Complete;
info.Percent = 100;
g_download_process_callback(info);
}
}

7、mswindows.c,添加下载进度提示

View Code

float g_fOldPercent = -1;

void send_download_process_info(float percent)
{
DownloadInfo info;
if(g_fOldPercent == floor(percent))
{
return ;
}
g_fOldPercent = floor(percent);
info.Percent = floor(percent);

info.pInfoStr = NULL;
if (info.Percent == 100)
{
info.InfoType = Complete;
}
else
{
info.InfoType = Loading;
}

if (g_download_process_callback != NULL)
{
g_download_process_callback(info);
}

}

在void ws_percenttitle (double percentage_float)函数中添加调用:send_download_process_info(percentage_float);

接下来就可以开始使用wget的函数直接进行下载了。\(^o^)/~

转载于:https://www.cnblogs.com/blueglass/archive/2011/07/04/2097583.html

使用 Visual Studio 编译 wget 为库文件相关推荐

  1. Visual Studio编译Lua库

    最近有空打算把lua的源码仔细看下,就用vs编个lib,需要细看时在断点进去看比较详细. 下面主要是编 链接库 和 解释器 的说明 Lua由三部分组成,即 Lua链接库 Lua解释器 Lua编译器 因 ...

  2. 【错误记录】Visual Studio 中配置 NDK 头文件路径 ( NDK 的三个头文件路径 | 与 CPU 架构相关 asm 头文件路径选择 )

    文章目录 一.报错信息 二.解决方案 1.NDK 的三个头文件路径 2.与 CPU 架构相关 asm 头文件路径选择 一.报错信息 参考 [Android 逆向]Android 进程注入工具开发 ( ...

  3. 使用Visual Studio来创建动态库/静态库,并加载

    使用Visual Studio来创建动态库 第一步新建一个控制台程序 第二步去掉SDL安全开发周期,以及选中创建DLL空项目 在资源管理器中添加.h和.cpp文件 在.h文件里可以写上函数的声明: # ...

  4. 一文带你弄懂Visual Studio:运行时库及MT/MTD、MD/MDD

    一文带你弄懂Visual Studio:运行时库及MT/MTD.MD/MDD 引子 什么是Runtime Library? Runtime Library和运行库 MT MTD MD MDD的关系 静 ...

  5. Libtorch:Linux系统中使用libtorch【下载、解压】【下载的libtorch是编译好的库文件,可直接使用】

    这几天学习C++部署深度模型,看到libtorch是现在人人都可以用普遍方法 1 安装opencv版本一定要3.4.12,否则与libtorch共同编译产生错误 linux上安装库或者程序,一个是编译 ...

  6. lua基础学习(1):使用Visual Studio编译lua和luac

    lua基础学习(1):使用Visual Studio编译lua和luac 0. 背景 本篇博客作为lua基础学习的第一篇博客,主要介绍使用Visual Studio对lua5.0进行编译,目的是获得l ...

  7. visual studio项目 .sln .vcxproj .vcproj 文件的区别和关系

    问题 一个开源工程,不知道其使用的VS版本,用VS2015打开,发现有两类工程文件,.vcproj和.vcxproj *.vcproj:VS2008以及VS2008之前版本的VS工程文件 *.vcxp ...

  8. 解决通过 Visual Studio 打不开 ui 文件的问题

    解决通过 Visual Studio 打不开 ui 文件的问题 在第一次使用 Visual Studio IDE 通过 Qt 平台来进行开发界面的时候,当双击 .ui 文件将其打开后,发现打开的 窗口 ...

  9. 【Qt】Visual Studio编译Qt项目报Qt Version错误

    00. 目录 文章目录 00. 目录 01. 问题描述 02. 开发环境 03. 问题分析 04. 问题解决 05. 附录 01. 问题描述 使用Visual Studio编译Qt项目时候,报以下错误 ...

最新文章

  1. 2017年5个最佳网络监控工具 你知道哪些
  2. phalcon: 解决php7/phalcon3.2以上版本,不支持oracle数据库的方法
  3. 求一颗二叉树中两个节点的最低公共父节点
  4. 江西一级b计算机考试报名,全国计算机等级考试一级b
  5. STL源码剖析 __type_traits
  6. 全局事件总线 (GlobalEventBus)
  7. 操作属性之修改样式属性
  8. 【第二周】四人小组:车辆管理系统
  9. Atitit。木马病毒原理机密与概论以及防御
  10. java环境问题_1_JAVA语言的特点及配置环境问题
  11. qpsk matlab仿真,qpsk的matlab和simulink仿真.pdf
  12. 绘制柱状图,填充不同颜色
  13. matlab如何写一个循环,matlab中for循环怎么写
  14. QCC3040---coredump方法和注意事项
  15. python导入模块不存在_基于pycharm导入模块显示不存在的解决方法
  16. 去除firefox火狐更新提示
  17. 基于固件的漏洞挖掘方法梳理
  18. JSRPC: WebSocket报错 Refused to connect to ‘ws:<URL>/ws?group=testname=wangluozhe‘ because it violate
  19. rancher 启动命令_Rancher 中文文档 —— 快速入门指南
  20. TM1638驱动数码管的一点建议,附程序

热门文章

  1. 嵩天python笔记_嵩天Python学习笔记-05
  2. ngrok服务器搭建_利用暴露在外的API,无法检测的Linux恶意软件将矛头指向Docker服务器...
  3. android照片备份软件下载,照片备份云相册app下载-照片备份云相册下载V1.9安卓版-西西软件下载...
  4. python+robotframework_python+robot framework接口自动化测试
  5. 无线打印 airprint 服务器,如何让 Windows 的共享打印机支持 AirPrint
  6. Sublime Text3常用基本操作
  7. 国内外知名光端机品牌大全
  8. [渝粤教育] 广东-国家-开放大学 大学英语2
  9. 【渝粤教育】电大中专消费者行为学30分钟交卷作业 题库
  10. 【渝粤教育】电大中专学前儿童健康教育_1作业 题库