日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用 Visual Studio 编译 wget 为库文件

發布時間:2023/12/2 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用 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函數變量定義之后添加如下代碼:

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 为库文件的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。