libcurl
Übersicht BlitzBasic DLLs und Userlibs
ThunderBetreff: libcurl |
Fr, Nov 13, 2015 1:16 Antworten mit Zitat |
|
---|---|---|
Hallo alle miteinander
ich glaube das ist mein erster Eintrag hier. Eigentlich tu ich nichts mehr mit BB, aber heute hatte ich irgendwie (nicht ganz zufällig) Lust, ein libcurl Binding zu schreiben. Also eine kleine feine API für BlitzBasic mit der man mit libcurl Sachen herunterladen kann. Ich habe es gerade getestet und es _scheint_ zu funktionieren. Verbesserungsvorschläge, Fehlerreports etc sind gerne willkommen, Änderungen und eigene Versionen explizit erlaubt. Starten wir Mal: Ich verwende das curl_easy_* interface. Leider braucht man da eine Callback-Funktion und BB unterstützt ja keine function pointer. Also habe ich die libcurl 7.45.0 geladen, selber etwas dazu programmiert und sie kompiliert. Mein hinzugefügter Code ist folgender: Code: [AUSKLAPPEN] #include <assert.h>
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #include <curl/curl.h> struct Download { enum { DOWNLOAD_DEST_BUFFER, DOWNLOAD_DEST_FILE } dst; union { struct { char *buffer; size_t buffer_i, buffer_len; }; struct { FILE *stream; const char *filename; }; }; }; static size_t write_callback(void *buffer, size_t size, size_t nmemb, void *stream) { if(stream == NULL) assert(0); struct Download *out = (struct Download *)stream; if (out->dst == DOWNLOAD_DEST_FILE){ if(out->stream == NULL) { out->stream = fopen(out->filename, "wb"); if (out->stream == NULL) return 0; } return fwrite(buffer, size, nmemb, out->stream); }else if(out->dst == DOWNLOAD_DEST_BUFFER){ if(out->buffer == NULL){ out->buffer_len = 4096; out->buffer = malloc(out->buffer_len); out->buffer_i = 0; } const size_t nlen = size*nmemb; if (nlen + out->buffer_i > out->buffer_len) { const size_t plus = nlen + 4096; char *nb = realloc(out->buffer, out->buffer_len + plus); if(nb == NULL) return 0; out->buffer = nb; out->buffer_len += plus; } memcpy(out->buffer+out->buffer_i, buffer, nlen); out->buffer_i += nlen; return nmemb; }else { assert(0); } } __declspec(dllexport) int curl_easy_download_file(CURL *handle, const char *url, const char *filename) { struct Download dl = { .dst = DOWNLOAD_DEST_FILE, .filename = filename, .stream = NULL }; curl_easy_setopt(handle, CURLOPT_URL, url); curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_callback); curl_easy_setopt(handle, CURLOPT_WRITEDATA, &dl); const int status = curl_easy_perform(handle) == 0 ? 1 : 0; fclose(dl.stream); return status; } __declspec(dllexport) int curl_easy_download_bank(CURL *handle, const char *url, void **dlptr) { struct Download dl = { .dst = DOWNLOAD_DEST_BUFFER, .buffer = NULL, }; curl_easy_setopt(handle, CURLOPT_URL, url); curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_callback); curl_easy_setopt(handle, CURLOPT_WRITEDATA, &dl); const int status = curl_easy_perform(handle) == 0 ? 1 : 0; *dlptr = malloc(sizeof(dl)); if(*dlptr == NULL) return 0; memcpy(*dlptr, &dl, sizeof(dl)); return status; } __declspec(dllexport) int32_t curl_easy_bank_size(struct Download *dlptr) { return dlptr->buffer_i; } __declspec(dllexport) void curl_easy_move_bank(struct Download *dlptr, char *newbank) { memcpy(newbank, dlptr->buffer, dlptr->buffer_i); free(dlptr->buffer); free(dlptr); } Decls: Code: [AUSKLAPPEN] .lib "libcurl.dll"
curl_easy_init%():"curl_easy_init" curl_easy_cleanup(handle%):"curl_easy_cleanup" curl_easy_download_file%(handle%, url$, filename$):"curl_easy_download_file" curl_easy_download_bank%(handle%, url$, tmpbank*):"curl_easy_download_bank" curl_easy_bank_size%(dlhandle%):"curl_easy_bank_size" curl_easy_move_bank%(dlhandle%, bank*):"curl_easy_move_bank" Und noch eine freundliche API als BlitzBasic-Funktionen: BlitzBasic: [AUSKLAPPEN]
Beispiel: BlitzBasic: [AUSKLAPPEN] LINK$ = "http://curl.haxx.se/libcurl/c/curl_easy_perform.html" Habe euch die DLL hier hochgeladen: https://www.blitzforum.de/upload/file.php?id=13083 (alte Version) Ihr könnt sie mit den Änderungen von mir auch selber bauen, wenn euch das lieber ist. Eine Standard-libcurl DLL kann man aber leider nicht verwenden. 30.09.2017 UPDATE version 7.54.1: https://drive.google.com/open?...XV2cmVCYWc Habe ne neue Version von der libcurl.dll mit meinen Erweiterungen gebaut. Allerdings nicht mit BB getestet, daher bleibt die alte Version, bis ich weiß, dass die neue auch funktioniert. Wenn möglich solltet ihr aktuelle Versionen verwenden, weil immer wieder Bugs gefunden und gefixt werden. Viel Spaß beim Probieren Edit: Meine Änderungen sind public domain (damit das klar ist). Edit2: Ich habe leider einen furchtbaren Fehler gemacht und in den Funktionsdeklarationen nicht __stdcall benutzt, daher wird der Stack nach dem Funktionsaufruf auf die DLL nicht wieder reduziert. Das kann zu sehr mysteriösen Abstürzen führen! Ich werde das demnächst fixen. Edit3: Problem gelöst. Die aktuellste Version auf google drive verwendet __stdcall Funktionen. ich lasse die alte Version aber noch drinnen, weil ich die neue nicht mit BB getestet habe. |
||
Meine Sachen: https://bitbucket.org/chtisgit https://github.com/chtisgit |
Übersicht BlitzBasic DLLs und Userlibs
Powered by phpBB © 2001 - 2006, phpBB Group