Всем привет,
Есть скрипт который использует libcurl.dll.
Установка опции CURLOPT_PROGRESSFUNCTION и CURLOPT_WRITEFUNCTION приводит к краху скрипта.
Использование этих опции необходима так как скрипт будет использоваться для скачивания файлов и отображения процесса скачивания.
Если закомментировать установку этих опции, то скрипт работает нормально, но файл не скачиваеться так как данные передаются в консоль.
Есть скрипт который использует libcurl.dll.
Установка опции CURLOPT_PROGRESSFUNCTION и CURLOPT_WRITEFUNCTION приводит к краху скрипта.
Использование этих опции необходима так как скрипт будет использоваться для скачивания файлов и отображения процесса скачивания.
Если закомментировать установку этих опции, то скрипт работает нормально, но файл не скачиваеться так как данные передаются в консоль.
Код:
#NoTrayIcon
OnAutoItExitRegister("_Close")
; curl_share_setopt : http://curl.haxx.se/libcurl/c/curl_share_setopt.html
Global Const $CURLE_OK = 0
Global Const $CURLOPT_TYPE_LONG = 0
Global Const $CURLOPT_TYPE_OBJECTPOINT = 10000
Global Const $CURLOPT_TYPE_FUNCTIONPOINT = 20000
Global Const $CURLOPT_VERBOSE = $CURLOPT_TYPE_LONG + 41
Global Const $CURLOPT_NOPROGRESS = $CURLOPT_TYPE_LONG + 43
Global Const $CURLOPT_SSL_VERIFYPEER = $CURLOPT_TYPE_LONG + 64
Global Const $CURLOPT_SSL_VERIFYHOST = $CURLOPT_TYPE_LONG + 81
Global Const $CURLOPT_URL = $CURLOPT_TYPE_OBJECTPOINT + 02
Global Const $CURLOPT_USERAGENT = $CURLOPT_TYPE_OBJECTPOINT + 18
Global Const $CURLOPT_HTTPHEADER = $CURLOPT_TYPE_OBJECTPOINT + 23
Global Const $CURLOPT_WRITEFUNCTION = $CURLOPT_TYPE_FUNCTIONPOINT + 11
Global Const $CURLOPT_PROGRESSFUNCTION = $CURLOPT_TYPE_FUNCTIONPOINT + 56
Global $hCURL_Dll = -1, $hCURL = -1, $sOutData = ""
Global $sOutFile = @ScriptDir & "\test_image.jpg"
If FileExists($sOutFile) Then FileDelete($sOutFile)
$sURL = "http://autoit-script.ru/Themes/RuNet/images/logor.jpg"
$hCURL_Dll = DllOpen("libcurl.dll")
If @error Or $hCURL_Dll = -1 Then Exit 99 * 0 + ConsoleWrite("DllOpen | " & @error & " \ " & @extended & " \ " & $hCURL_Dll & @CR)
$aRet = DllCall($hCURL_Dll, "ptr:cdecl", "curl_easy_init")
$hCURL = $aRet[0]
; URL
$tCURLSTRUCT_OPT = DllStructCreate("char[" & StringLen($sURL) + 1 & "]")
DllStructSetData($tCURLSTRUCT_OPT, 1, $sURL)
$aRes = DllCall($hCURL_Dll, "int:cdecl", "curl_easy_setopt", "ptr", $hCURL, "int", $CURLOPT_URL, "ptr", DllStructGetPtr($tCURLSTRUCT_OPT))
If @error Then Exit 99 * 0 + ConsoleWrite("curl_easy_setopt $CURLOPT_URL | " & @error & " \ " & @extended & " \ " & $aRes[0] & @CR)
; VERBOSE
; $aRes = DllCall($hCURL_Dll, "int:cdecl", "curl_easy_setopt", "ptr", $hCURL, "int", $CURLOPT_VERBOSE, "long", 1)
; If @error Then Exit 99 * 0 + ConsoleWrite("curl_easy_setopt $CURLOPT_VERBOSE | " & @error & " \ " & @extended & " \ " & $aRes[0] & @CR)
; NOPROGRESS
$aRes = DllCall($hCURL_Dll, "int:cdecl", "curl_easy_setopt", "ptr", $hCURL, "int", $CURLOPT_NOPROGRESS, "long", 0)
If @error Then Exit 99 * 0 + ConsoleWrite("curl_easy_setopt $CURLOPT_NOPROGRESS | " & @error & " \ " & @extended & " \ " & $aRes[0] & @CR)
; PROGRESSFUNCTION
$hProgress = DllCallbackRegister("_Progress", "int", "ptr;double;double;double;double") ; int function(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
$aRes = DllCall($hCURL_Dll, "int:cdecl", "curl_easy_setopt", "ptr", $hCURL, "int", $CURLOPT_PROGRESSFUNCTION, "ptr", DllCallbackGetPtr($hProgress))
If @error Then Exit 99 * 0 + ConsoleWrite("curl_easy_setopt $CURLOPT_PROGRESSFUNCTION | " & @error & " \ " & @extended & " \ " & $aRes[0] & @CR)
; WRITEFUNCTION
$hWriteFunc = DllCallbackRegister("_WriteFunc", "uint", "ptr;uint;uint;ptr") ; size_t function( char *ptr, size_t size, size_t nmemb, void *userdata)
$aRes = DllCall($hCURL_Dll, "int:cdecl", "curl_easy_setopt", "ptr", $hCURL, "int", $CURLOPT_WRITEFUNCTION, "ptr", DllCallbackGetPtr($hWriteFunc))
If @error Then Exit 99 * 0 + ConsoleWrite("curl_easy_setopt $CURLOPT_WRITEFUNCTION | " & @error & " \ " & @extended & " \ " & $aRes[0] & @CR)
; PERFORM
$aRes = DllCall($hCURL_Dll, "int:cdecl", "curl_easy_perform", "ptr", $hCURL)
If $aRes[0] <> $CURLE_OK Then
$aErr = DllCall($hCURL_Dll, "str:cdecl", "curl_easy_strerror", "int", $aRes[0])
Exit 99 * 0 + ConsoleWrite("curl_easy_strerror | " & $aRes[0] & " \ " & $aErr[0] & @CR)
EndIf
Func _Progress($clientp, $dltotal, $dlnow, $ultotal, $ulnow)
ConsoleWrite("_Progress | " & $dlnow & " \ " & $dltotal & @CR)
; ConsoleWrite("_Progress | " & $dlnow / $dltotal * 100 & ", " & StringFormat("%.2fKb (%.1f%%)", $dlnow / 1024, $dlnow / $dltotal * 100) & @CR)
Return 0 ; Returning a non-zero value from this callback will cause libcurl to abort the transfer
EndFunc ;==>_Progress
Func _WriteFunc($ptr, $size, $nmemb, $userdata)
Local $vData = DllStructCreate ("byte[" & $size*$nmemb & "]", $ptr)
$sOutData = $sOutData & DllStructGetData($vData, 1)
$hOutFile = FileOpen($sOutFile, 2)
FileWrite($hOutFile, $sOutData)
FileClose($hOutFile)
Return $size * $nmemb
EndFunc
Func _Close()
If IsDeclared("hProgress") Then DllCallbackFree(Eval("hProgress"))
If IsDeclared("hWriteFunc") Then DllCallbackFree(Eval("hWriteFunc"))
DllCall($hCURL_Dll, "none:cdecl", "curl_easy_cleanup", "ptr", $hCURL)
DllClose($hCURL_Dll)
Exit
EndFunc