Oppure

Loading
29/10/16 8:26
a_butta
Ciao a tutti.
Anche se con gran fatica, son riuscito alla fine ad installare la libreria cURL attraverso MSYS64.
cURL, di per sé, funziona: se lo avvio da linea di comando e testo l'acquisizione del sito google.com ricevo la pagina HTML.
Ora il problema è implementarlo nel mio programma (C++): uso eclipse (compilatore MinGW) e sto cercando di testare un semplicissimo GET. Per il collegamento con il compilatore ho seguito e istruzioni sul web e sfruttato il comando curl-config:

curl-config --cflags
-I/usr/local/include

curl-config --libs
-L/usr/local/lib -lcurl -lwldap32 -lz -lws2_32


Sono andato sotto le opzioni Build->Settings:
In GCC C++ Compiler->Includes e GCC C Compiler->Includes ho aggiunto il primo collegamento (ho usato un path assoluto: /msys64/usr/local/…). Sotto l'opzione MinGW C++ Linker->Miscellaneous, nel Linker flags ho copiato la risposta al secondo comando (sempre con path assoluto: -/msys64/usr/local/… -lcurl -lwldap32 -lz -lws2_32.

Sono dunque andato a prendere il file di esempio più semplice, trovato nel pacchetto curl:

int main()
{
	  CURL *curl;
	  CURLcode res;

	  curl = curl_easy_init();
	  if(curl) {
	    curl_easy_setopt(curl, CURLOPT_URL, "http://www.google.com/");
	    res = curl_easy_perform(curl);

	    if(CURLE_OK == res) {
	      char *ct;
	      /* ask for the content-type */
	      res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct);

	      if((CURLE_OK == res) && ct)
	        cout << std::string(ct);
	    }

	    /* always cleanup */
	    curl_easy_cleanup(curl);
	  }

    return 0;
}


Ho modificato soltanto la stampa a video sostituendo ad uno fprintf il std::cout con conversione da char* a std::string.

Fatto il Build nessun tipo di errore: Tutto ok

Avvio il programma: termina l'avvio ed esce con exit value:-1.073.741. Cioé, non mi da ALCUN TIPO DI ERRORE ma non esegue il pezzo di codice per intero (per intenderci non arriva al return 0 del main).
Stessa identica cosa in modalità Debug: non riesco ad effettuarlo perchè il programma esce prima che possa interrompersi nel main (sembra quasi che non riesca proprio ad entrarci).

Sono alquanto incredulo... Qualche suggerimento?

Ringrazio anticipatamente
Ultima modifica effettuata da a_butta 29/10/16 8:34
aaa
29/10/16 13:56
a_butta
Sono riuscito a capire qualcosa in più.

Ho notato che il problema è a monte di tutto nell'inizializzazione curl_easy_init(curl). Infatti, apponendo un return 1; prima di questo, l'applicazione termina correttamente.

Andando ad avviare il programma direttamente da linea di comando (cmd) ottengo l'errore Libreria libcurl-4.dll non trovata. Dunque sono andato a porre il link a tale libreria nella variabile PATH dell' ambiente windows. Risultato: da linea di comando il programma funziona!

Ritorno su Eclipse: stesso problema. L'applicazione esce con valore diverso da zero e non funziona come prima...

Qualche suggerimento?
aaa
29/10/16 14:10
GN
Penso che le possibili soluzioni siano 2:
- copiare la dll nella cartella dell'eseguibile e distribuirla insieme ad esso (probabilmente c'è un modo per farlo fare automaticamente ad Eclipse, ma non ne sono al corrente), comunque puoi prvare a mano.
- linkare staticamente invece che dinamicamente, in modo che tutto il necessario finisca dentro all'eseguibile; in tal caso dovresti trovare la versione statica di quella libreria (se non sbaglio su Windows l'estensione dovrebbe essere .lib, oppure .a come su Linux) ed inserire il suo percorso nella riga di comando del linker, es. "/msys64/usr/local/lib/…" al posto di " -/msys64/usr/local/… -lcurl".

Inoltre avendo la libreria curl altre dipendenze ("-lwldap32 -lz", ws2 se non sbaglio non dovrebbe essere un problema perchè essendo la Winsock è già presente in Windows) probabilmente bisognerà ripetere l'operazione anche per queste 2.
Ultima modifica effettuata da GN 29/10/16 14:11
aaa
29/10/16 14:22
a_butta
Postato originariamente da GN:
- copiare la dll nella cartella dell'eseguibile e distribuirla insieme ad esso (probabilmente c'è un modo per farlo fare automaticamente ad Eclipse, ma non ne sono al corrente), comunque puoi prvare a mano.


Sulla prima possibilità hai fatti bingo! E già per questo ti ringrazio tanto!
Scusami però devo farti una domanda da ignorante. Se dovessi compilare il mio codice su Linux, come dovrei fare? In questo modo non funzionerebbe, erro?

Postato originariamente da GN:
- linkare staticamente invece che dinamicamente, in modo che tutto il necessario finisca dentro all'eseguibile; in tal caso dovresti trovare la versione statica di quella libreria (se non sbaglio su Windows l'estensione dovrebbe essere .lib, oppure .a come su Linux) ed inserire il suo percorso nella riga di comando del linker, es. "/msys64/usr/local/lib/…; al posto di " -/msys64/usr/local/… -lcurl".


Nel frattempo provo a vedere col secondo metodo. Nella cartella lib ho quattro file "allettanti":
-) libcurl.a
-) libcurl.dll
-) libcurl.dll.a
-) libcurl.la
Quale dovrei collegare nel linker? Inoltre secondo il tuo esempio dovrei apporre /msys64/usr/local/lib/…. In questo modo non funziona... La mancanza del tag prima del collegamento è necessaria? (intendo -l per la libreria o -L per la cartella)
aaa
29/10/16 19:24
GN
Su linux stessa cosa, puoi linkare staticamente o dinamicamente. Di solito non si distribuiscono le librerie dinamiche (.so) insieme agli eseguibili ma si lascia risolvere la dipendenza dal package manager della distribuzione. In teoria comunque si può fare, tenendo conto che di default le librerie dinamiche non vengono cercate nella cartella di lavoro ma solo nei percorsi di sistema (es. /usr/lib, /usr/local/lib), quindi prima di avviare il programma bisogna settare la variabile d'ambiente LD_LIBRARY_PATH=. per fare in modo che vengano cercati i .so nella cartella di lavoro.
Che io sappia comunque è un metodo sconsigliabile, di solito si distribuiscono i pacchetti per le varie distribuzioni (.deb, .rpm, ecc) contenenti solo il programma vero e proprio e/o un .tar.gz con i sorgenti e la documentazione per compilare. Quando si genera il pacchetto si specificano le dipendenze necessarie e sarà il package manager a risolverle al momento dell'installazione sul computer dell'utente.
Sto andando leggermente OT, comunque consiglio questo tool per costruire pacchetti per varie distribuzioni: github.com/jordansissel/…, è abbastanza ben documentato ed è molto comodo perchè consente di generare pacchetti in vari formati con un solo comando.

Per la questione del linking statico che errore ottieni? L'avevo fatto tempo fa ma non ricordo bene, dovrebbe essere spiegato nella documentazione di curl. Mi viene in mente ora che bisogna anche specificare -DCURL_STATIC_LIB al compilatore.
aaa