使用 Visual Studio 编译 wget 为库文件

添加代码与预编译指令与上一篇使用 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函数变量定义之后添加如下代码:

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

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

ContractedBlock.gifExpandedBlockStart.gifView 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、外部调用下载所用函数:

ContractedBlock.gifExpandedBlockStart.gifView 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函数使用

ContractedBlock.gifExpandedBlockStart.gifView 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函数

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

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

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

ContractedBlock.gifExpandedBlockStart.gifView 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函数中添加下载进度提示

ContractedBlock.gifExpandedBlockStart.gifView 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,添加下载进度提示

ContractedBlock.gifExpandedBlockStart.gifView 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/362131.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

动态规划(0-1背包)--- 改变一组数的正负号使得它们的和为一给定数

改变一组数的正负号使得它们的和为一给定数 494. Target Sum (Medium) Input: nums is [1, 1, 1, 1, 1], S is 3. Output: 5 Explanation:-11111 3 1-1111 3 11-111 3 111-11 3 1111-1 3There are 5 ways to assign symbols to make the sum of nums be target 3. 题目描述…

关于设计模式的胡思乱想

设计模式是一个指导&#xff0c;并不强制。有很多地方并不需要设计模式介入&#xff0c;因为设计模式是分离变化&#xff0c;很多代码是一次性的&#xff0c;不会变。如果我们一开始写程序的时候就加入设计模式&#xff0c;这样就显得过度设计&#xff0c;既耗时又费力。 并且…

JSR 310新日期/时间API的自定义JSR 303 Bean验证约束

借助JSR 310&#xff0c;Java 8终于为我们带来了不错的日期和时间API。 对于仍在使用Java 7的那些人&#xff08;例如我目前在我的当前项目中&#xff09;&#xff0c;有很好的反向移植&#xff0c;请访问www.threeten.org了解更多详细信息。 但是&#xff0c;由于有关该主题的…

H5之audio标签放音兼容所有浏览器方法

前端交流群&#xff0c;群文件提供大量文档、书籍和资料。期待你的加入&#xff01;群号&#xff1a;127768464 由于项目需要&#xff0c;最近刚做了一个网页放音的功能&#xff0c;使用到了H5新标签<audio></audio>&#xff0c;但是audio只能支持IE8以上的浏…

VisualStudio2010 SP1 SP1 SDK SQLServer 2008 SP3 下载地址

SP1:http://go.microsoft.com/fwlink/?LinkId210710 SP1 SDK:http://www.microsoft.com/download/en/details.aspx?id21835 SQLServer2008 sp3:http://www.microsoft.com/downloads/zh-cn/details.aspx?familyid757bca07-7b52-46fb-ab92-476be9339442&displaylangzh-cn …

python高级特性:迭代器与生成器

前言 有一个列表 l [a,b,c,d,e] 我想取列表中的内容&#xff0c;有几种方式&#xff1f; # 1.最简单的方法用for循环。 for i in l:print(i,end" ") # 2.用列表内置的方法。 while 1:if l:print(l.pop(),end" ") 这是用常见的方式取出列表中的数据。 …

webpack中实现按需加载

当页面中一个文件过大并且还不一定用到的时候&#xff0c;我们希望在使用到的时候才开始加载这个文件俗称按需加载。这样可以减少页面的响应时间&#xff0c;提高访问速度。 使用webpack打包的出来的文件要实现以上的要求有两种方式&#xff0c;一个是webpack特有的require.en…

H5各种头部meta标签的功能

<!DOCTYPE html> H5标准声明&#xff0c;使用 HTML5 doctype&#xff0c;不区分大小写 <head lang”en”> 标准的 lang 属性写法 <meta charset’utf-8′> 声明文档使用的字符编码 <meta http-equiv”X-UA-Compatible” content”IEedge,chrome1″…

如何使用单例EJB和MBean构建和清除参考数据缓存

在我的一个项目中&#xff0c;我需要使用EclipseLink作为ORM框架从Java EE 6 WebLogic环境中的多个源中加载参考数据。 由于我在Java EE世界中找不到与Spring YET的Cacheable相当的注释&#xff0c;因此我不得不编写自己的缓存解决方案。 尽管参考数据几乎不会随时间变化&#…

让 UV4 支持STC 单片机

Keil 本身并没有自带 STC 8051 单片机的数据&#xff0c;这样用起来就非常令人不爽&#xff0c;好在国内有个青年已经整理了一个补丁。 这个补丁包含三个修正&#xff1a; 汉字bug修正&#xff0c;这个是老生常谈了&#xff0c;很奇怪Keil十年来都没有修正这个&#xff0c;说明…

【总结】计算机网络常见问题

1、TCP/IP协议与OSI协议 相互通信的两个计算机系统必须高度协调工作才行&#xff0c;而这种“协调”是相当复杂的。 “分层”可将庞大而复杂的问题&#xff0c;转化为若干较小的局部问题&#xff0c;而这些较小的局部问题就比较易于研究和处理。 计算机网络采用了分层的体系结构…

webpack3的CommonsChunkPlugin插件详解

webpack打出来的包在不做处理的情况下是非常大的&#xff0c;所有依赖都被塞进一个文件中&#xff0c;文件中有业务代码&#xff0c;有业务代码依赖的第三方库代码&#xff0c;还有webpack生成的运行时代码等。这样的一个文件不方便静态资源缓存&#xff0c;并且初始化页面的时…

详细介绍jQuery.outerWidth() 函数具体用法

outerWidth()函数用于设置或返回当前匹配元素的外宽度。外宽度默认包括元素的内边距(padding)、边框(border)&#xff0c;但不包括外边距(margin)部分的宽度。你也可以指定参数为true&#xff0c;以包括外边距(margin)部分的宽度。如下图&#xff1a; 如果你要获取其它情况的宽…

自动装箱

自Java 1.5起&#xff0c;所有Java开发人员都可以使用自动装箱功能。嗯&#xff0c;我可能太乐观了。 至少所有开发人员都应该可以使用自动装箱。 毕竟&#xff0c;在ORACLE页面上有一个很好的教程。 自动装箱是Java编译器在需要时自动从原始类型创建代码创建对象的代码时的现…

SQLite 入门教程(一)基本控制台(终端)命令

一、基本简介 SQLite 是一个自持的&#xff08;self-contained&#xff09;、无服务器的、零配置的、事务型的关系型数据库引擎。因为他很小&#xff0c;所以也可以作为嵌入式数据库内建在你的应用程序中。SQLite 被应用在 Solaris 10操作系统、Mac OS 操作系统、iPhone 和 Sky…

PHP中的session

1.1原理 1.session是服务器端的技术 2.session是基于cookie技术的 1.2session操作 1.默认情况下&#xff0c;会话不会自动开启&#xff0c;通过session_start()开启会话 2.通过session_id()获取会话的编号 3、通过$_SESSION操作会话 4、会话可以保存除了资源以外的所有类型…

Web前端开发css基础样式总结

颜色和单位的使用 颜色 用颜色的名字表示颜色,比如:red 用16进制表示演示 比如:#FF0000 用rgb数值表示颜色,rgb(红,绿,蓝),每个值都在0-255之间 一般都用16进制表示颜色 单位 1. px像素&#xff08;Pixel&#xff09;。像素,与分辨率…

nth-child(n)和nth-of-type(n)

:nth-child(n)&#xff1a;父元素的子元素的第n个 :nth-of-type(n)&#xff1a;父元素的 某类 子元素的第n个 注&#xff1a;n从0起&#xff0c;元素index从1起 nth-child(n)和nth-of-type(n)例&#xff1a; <head><style>body :nth-child(2) {height: 30px;ba…

Spring WebApplicationInitializer和ApplicationContextInitializer的混淆

我偶尔会混淆这两个概念-WebApplicationInitializer和ApplicationContextInitializer&#xff0c;并希望描述它们中的每一个&#xff0c;以便为我自己澄清它们。 我以前在这里写过有关WebApplicationInitializer的博客。 它仅在符合Servlet 3.0规范的Servlet容器中相关&#x…

Mysql修改binlog日志过期时间

1.临时生效 # 查看默认设置的过期时间 show variables like "%expire_logs%"; # 设置保留15天 set global expire_logs_days15 # 刷新日志 flush logs&#xff1b; #查看新生成的binlog日志 show master status\G: 注意&#xff1a;以上命令在数据库执行会立即生效&a…