Что нового

libcurl c опциями PROGRESSFUNCTION и WRITEFUNCTION приводит к краху скрипта

XpycT

Скриптер
Сообщения
380
Репутация
133
Всем привет,

Есть скрипт который использует 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
 
Автор
X

XpycT

Скриптер
Сообщения
380
Репутация
133
Я так понимаю никто не пробовал работать с libcurl :(
 
Верх