Nieśmiertelny temat - instalacja cURL . Tutaj - Visual Studio 2010 Premium student

0

Pobrana biblioteka:

MSVC metalink 7.19.3 devel SSL enabled Frederic Elbin 4.04 MB

Nazwa projektu: curl_compilation ( otwarty z "empty project")
W projekcie znajduje się jeden plik: main.cpp

//#include "stdafx.h"
#include <stdio.h>
#include <curl/curl.h>


int main(void)
{
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http://www.cnn.com/");
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
}
return 0;
}

intelli sense z oczywistych względów podkreśla większą część programu na czerwono...

Project->curl_compilation Properties->Configuration Properties-> C\C++ -> General

Additional Include Directories: C:\cURL\libcurl-7.19.3-win32-ssl-msvc\include;%(AdditionalIncludeDirectories)

... ale przestaje po powyższej zmianie we właściwościach projektu, niestety tylko dla trybu "debug".

output debugera dla opcji "debug"

1> main.cpp
1>main.obj : error LNK2019: unresolved external symbol __imp__curl_easy_cleanup referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol __imp__curl_easy_perform referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol __imp__curl_easy_setopt referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol __imp__curl_easy_init referenced in function _main

dla opcji relase jest tylko lakoniczne "cannot open <curl/curl.h>"

I to wszystko bez znaczenia jaką CRT wybiorę.

Wiem, temat był wałkowany miliardy razy, ale żaden na tym ani na innych forach nie udzielił mi dostatecznych informacji, a siedzę już piąta godzinę nad instalacją tej biblioteki.

Próbowałem też odpalić plik curl.exe , wtedy wyskoczył messagebox:

The program can't start because libsasl.dll is missing from your computer. Try reinstalling the program to fix this problem

Po pobraniu tej nieszczęsnej biblioteki stąd:
http://www.dlldll.com/libsasl.dll_download.html

message box zmienia swoją treść, ale niestety dalej uderza obleśną melodyjką i białym krzyżykiem na czerwonym tle

The procedure entry point sasl_errdetail could not be located in the dynamic lik library libsasl.dll

Co robić ? Jak żyć? Fajnie gdyby udałoby się w tym temacie rozwiązać ten problem, wtedy byłyby on jedynym w którym zawarte są wszystkie instrukcje niezbędne do zainstalowania najnowszego wydania cURL'a :)

1

Nazwa projektu: curl_compilation ( otwarty z "empty project")

Zamiast tworzyć projekt od zera, stwórz go z kreatora, po to on tam jest. Zawartość main przekopiuj do wygenerowanej wersji tej funkcji. Jeśli chodzi o konfigurację środowiska/projektu, powinieneś dodać jeszcze ścieżki do bibliotek importów lib i źródeł src. Zapewne będziesz musiał dołączyć biblioteki .lib do projektu (masz tam dwie wersje bibliotek: curllib.lib i curllib_static.lib, wybierasz tylko jedną z nich).

To tak na szybko...

0

Zamiast tworzyć projekt od zera, stwórz go z kreatora, po to on tam jest.

Chodzi Ci o New Project(ctrl+shift+n) -> Installed Templates ->Visual C++ -> Class Library?

Sorki że pytam o takie oczywiste oczywistości, ale ja i zapewne wiele osób które przejrzy ten temat pierwszy raz instaluje jakiekolwiek third party library( nie wiem jak to się tłumaczy :P)

I jeszcze jedna rzecz - czyli ten program curl.exe jest niepotrzebny? Bo właśnie ściągnąłem program Pidgin tylko po tą bibliotekę, teraz po jego odpaleniu tego exe'ca pojawia się konsola i natychmiast znika.

1

Chodzi Ci o New Project(ctrl+shift+n) -> Installed Templates ->Visual C++ -> Class Library?

Nie, chodzi mi o New Project -> Visual C++ -> Win32 -> <tu sobie wybierasz albo konsola, albo typowa aplikacja> (pewne rzeczy mogą się różnić, bo mam dość starą wersję visuala).

czyli ten program curl.exe jest niepotrzebny?

Tak sądzę.

0
0x666 napisał(a)

Zamiast tworzyć projekt od zera, stwórz go z kreatora, po to on tam jest.(1) Zawartość main przekopiuj do wygenerowanej wersji tej funkcji. Jeśli chodzi o konfigurację środowiska/projektu, powinieneś dodać jeszcze ścieżki do bibliotek importów lib i źródeł src.(2) Zapewne będziesz musiał dołączyć biblioteki .lib do projektu (masz tam dwie wersje bibliotek: curllib.lib i curllib_static.lib, wybierasz tylko jedną z nich).(3)

To tak na szybko...

1)ok, stworzyłem Win32 console aplication z kreatora
2)w tym samym miejscu co ( includeProject->curl_compilation Properties->Configuration Properties-> C\C++ -> General->Additional Include Directories)?
3)curllib.lib albo curllib_static.lib dodać za pomocą Solution explorer -> Source files -> Existing item(Shift + alt + a)?

0

Zamiast z takimi pierdołami na forum to po prostu poszukaj w google jak się linkuje biblioteki w msvc. Nikt przecież nie będzie się tu rozpisywał gdzie po kolei kliknąć, biorąc pod uwagę, że różnice mogą być między wersjami, a może nawet edycjami vs

0
byku_guzio napisał(a)

Zamiast z takimi pierdołami na forum to po prostu poszukaj w google jak się linkuje biblioteki w msvc. Nikt przecież nie będzie się tu rozpisywał gdzie po kolei kliknąć, biorąc pod uwagę, że różnice mogą być między wersjami, a może nawet edycjami vs

Nie bez powodu stworzyłem temat w takim a nie innym dziale. Nawet jeśli są "różnice między wersjami, a może nawet edycjami vs" , to ktoś może powiedzieć jak to się robi starszej wersji(przy okazji uporządkowując i ugruntowując własną wiedzę). Na pewno cośtam przełomowego to by wniosło, prędzej niż Twoje "poszukaj w google"...

1

Skoro sądzisz, że Ci to pomoże... Właściwości projektu->Linker->General->Additional Library Directories i może być jeszcze konieczne dodanie odpowiedniego lib'a w Linker->Input->Additional Dependencies (to zależy czy nagłówki curl'a mają dyrektywy dołączające lib'y czy nie).

Pomyśl co będzie jak przed użyciem będziesz musiał jakąś bibliotekę jeszcze zbudować... Jak chcesz programować to musisz nauczyć się wyszukiwać informacji, bo z takimi problemami będziesz się spotykał na co dzień.

//tu masz jeszcze przydatne linki, żebyś mógł się zorientować ocb i mieć jakiś punkt zaczepienia w dalszym poszukiwaniu:
http://pl.wikipedia.org/wiki/Preprocesor
http://pl.wikipedia.org/wiki/Kompilator
http://pl.wikipedia.org/wiki/Konsolidator

1

2)w tym samym miejscu co ( includeProject->curl_compilation Properties->Configuration Properties-> C\C++ -> General->Additional Include Directories)?

Tools -> Options -> VC++ Directories, reszty się domyślisz. src możesz sobie odpuścić, bo i tak tam nie ma żadnych plików źródłowych. W ten sposób "instalujesz" biblioteki w środowisku globalnie, tzn. że załączanie biblioteki w każdym następnym cURLowym projekcie ograniczasz jedynie do punktu 3.

3)curllib.lib albo curllib_static.lib dodać za pomocą Solution explorer -> Source files -> Existing item(Shift + alt + a)?

Project -> properties -> Linker -> Input -> Addictional dependiencies.

0

Już chyba jestem blisko

1

Pisałem, żebyś skopiował zawartość main z przykładu a nie całą funkcję! Przecież gołym okiem widać, że visualowa int _tmain(int argc, _TCHAR* argv[]) to nie int main(void).

Spróbowałem u siebie, i tak:

  • w Tools -> Options -> VC++ Directories -> Library Files dodaj katalog <curl>\lib\Release. Include Files tak jak wcześniej.
  • w Addictional dependiencies dodaj curllib.lib.
  • do katalogu z exekiem skopiuj curllib.dll, libeay32.dll, openldap.dll i ssleay32.dll.

Powinno śmigać ;)

Próbowałem skompilować z curllib_static, ale biblioteka chyba jest skompilowana na nowszym kompilatorze i się jakaś chvjnia z niezgodnością niektórych funkcji CRT robi, więc sobie darowałem drążenie tematu.

0

U mnie curllib_static.lib też nie działa. Za to przy curllib.lib program się uruchamia, niestety zaraz po włączeniu się konsoli pojawia się komunikat "Program nie może znaleźć curllib.dll na tym komputerze". Dziwne, po plik ten ma aż 3 kopie w folderze C:\cURL. Nic się nie zmienia nawet po uruchomieniu VS jako administrator...

PS. Nie zauważyłem 3 punktu . Zaraz sprawdzę.

PS2.

Wygląda na to że będę miał co opijać w weekend :) Dzięki wielkie za pomoc!

1

Dodawanie ścieżek include i libraries w preferencjach całego Visual Studio jest deprecated. Od VS2010 powinno się to wszystko robić przez property sheets. W skrócie: jest to budowanie preferencji projektu z małych klocków. Wszystkie zmiany w preferencjach projektu dotyczące dołączenia biblioteki możemy wydzielić w postaci takiego property sheet.

View -> Other windows -> Property manager
Powiedzmy, że chcemy do naszej wersji release dołączyć statycznie bibliotekę cURL również w wersji release. No to prawym na "Release" i dodajemy nowy property sheet, który nazwiemy "cURL Library (Static)". I teraz w tym property sheet ustawiamy wszystko co dotyczy dołączenia biblioteki.

Sensownie jest trzymać nasze biblioteki w jakiejś ogarniętej lokalizacji. Może to być jakaś lokalizacja zewnętrzna (ja np. trzymam wszystkie biblioteki w katalogu D:\SharedLibs) albo katalog w solucji, np. "Dependencies". Wrzucanie plików nagłówkowych i libów do katalogów Visual Studio to barbarzyństwo.

No to jedziemy:
C/C++ -> General -> Additional Include Directories: D:\SharedLibs\cURL\7.9.13\include
Linker -> General -> Additional Library Directories: D:\SharedLibs\cURL\7.9.13; D:\SharedLibs\cURL\7.9.13\lib\Release
Linker -> Input -> Additional Dependencies: curllib_static.lib;Ws2_32.lib;libeay32.lib;openldap.lib;ssleay32.lib
Build events -> Post-build event:

copy /Y "D:\SharedLibs\cURL\7.9.13\openldap.dll" "$(OutputPath)"
copy /Y "D:\SharedLibs\cURL\7.9.13\libsasl.dll" "$(OutputPath)"
copy /Y "D:\SharedLibs\cURL\7.9.13\ssleay32.dll" "$(OutputPath)"
copy /Y "D:\SharedLibs\cURL\7.9.13\libeay32.dll" "$(OutputPath)"

No dobra, ale skąd te biblioteki dll, skoro mieliśmy cURL zlinkować statycznie. Ok, zlinkowaliśmy tę bibliotekę statycznie i przenieśliśmy tą zależność do naszego pliku wykonywalnego, ale sam cURL też ma zależności! Gdyby zostały nam dostarczone te biblioteki skompilowane statycznie, również moglibyśmy się pozbyć tych dodatkowych bibliotek.
Do swojego projektu dodałem również bibliotekę libsasl.dll, która jest zależnością openldap.dll. Autor prawdopodobnie tego nie zauważył, miał bibliotekę w swoim systemie i sprawę olał. A ja na swoim systemie miałem tę bibliotekę tylko w wersji 64-bitowej i cały program się malowniczo wywalał. Ale od takich rzeczy jest Dependency Walker, który po otworzeniu mojego pliku wykonywalnego zaczął mi o tym krzyczeć i naprawienie problemu zajęło chwilę.

0

Heh za wcześnie się ucieszyłem. Przyszło wklepać konkretniejszy przykład i już są problemy =(. Właściwie jeden jedyny błąd, ale nie mam pomysłu jak go naprawić.

// ftpupload_with_wizard.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

/*****************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * $Id: ftpupload.c,v 1.15 2008-05-22 21:20:09 danf Exp $
 */

#include <stdio.h>
#include <string.h>

#include <curl/curl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#ifdef WIN32
#include <io.h>
#else
#include <unistd.h>
#endif

/*
 * This example shows an FTP upload, with a rename of the file just after
 * a successful upload.
 *
 * Example based on source code provided by Erick Nuwendam. Thanks!
 */

#define LOCAL_FILE      "/tmp/uploadthis.txt"
#define UPLOAD_FILE_AS  "while-uploading.txt"
#define REMOTE_URL      "ftp://localhost/"  UPLOAD_FILE_AS
#define RENAME_FILE_TO  "renamed-and-fine.txt"

/* NOTE: if you want this example to work on Windows with libcurl as a
   DLL, you MUST also provide a read callback with CURLOPT_READFUNCTION.
   Failing to do so will give you a crash since a DLL may not use the
   variable's memory when passed in to it from an app like this. */
static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
{
  /* in real-world cases, this would probably get this data differently
     as this fread() stuff is exactly what the library already would do
     by default internally */
  size_t retcode = fread(ptr, size, nmemb, stream);

  fprintf(stderr, "*** We read %d bytes from file\n", retcode);
  return retcode;
}

int _tmain(int argc, _TCHAR* argv[])
{
  CURL *curl;
  CURLcode res;
  FILE *hd_src;
  struct stat file_info;

  struct curl_slist *headerlist=NULL;
  static const char buf_1 [] = "RNFR " UPLOAD_FILE_AS;
  static const char buf_2 [] = "RNTO " RENAME_FILE_TO;

  /* get the file size of the local file */
  if(stat(LOCAL_FILE, &file_info)) {
    printf("Couldnt open '%s': %s\n", LOCAL_FILE, strerror(errno));
    return 1;
  }
  printf("Local file size: %ld bytes.\n", file_info.st_size);

  /* get a FILE * of the same file */
  hd_src = fopen(LOCAL_FILE, "rb");

  /* In windows, this will init the winsock stuff */
  curl_global_init(CURL_GLOBAL_ALL);

  /* get a curl handle */
  curl = curl_easy_init();
  if(curl) {
    /* build a list of commands to pass to libcurl */
    headerlist = curl_slist_append(headerlist, buf_1);
    headerlist = curl_slist_append(headerlist, buf_2);

    /* we want to use our own read function */
    curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);

    /* enable uploading */
    curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);

    /* specify target */
    curl_easy_setopt(curl,CURLOPT_URL, REMOTE_URL);

    /* pass in that last of FTP commands to run after the transfer */
    curl_easy_setopt(curl, CURLOPT_POSTQUOTE, headerlist);

    /* now specify which file to upload */
    curl_easy_setopt(curl, CURLOPT_READDATA, hd_src);

    /* Set the size of the file to upload (optional).  If you give a *_LARGE
       option you MUST make sure that the type of the passed-in argument is a
       curl_off_t. If you use CURLOPT_INFILESIZE (without _LARGE) you must
       make sure that to pass in a type 'long' argument. */
    curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
                     (curl_off_t)file_info.st_size);

    /* Now run off and do what you've been told! */
    res = curl_easy_perform(curl);

    /* clean up the FTP commands list */
    curl_slist_free_all (headerlist);

    /* always cleanup */
    curl_easy_cleanup(curl);
  }
  fclose(hd_src); /* close the local file */

  curl_global_cleanup();
  return 0;
}

 

1>------ Build started: Project: ftpupload_with_wizard, Configuration: Debug Win32 ------
1> ftpupload_with_wizard.cpp
1>c:\users\tabaluga\documents\visual studio 2010\projects\ftpupload_with_wizard\ftpupload_with_wizard\ftpupload_with_wizard.cpp(51): error C2664: 'fread' : cannot convert parameter 4 from 'void *' to 'FILE '
1> Conversion from 'void
' to pointer to non-'void' requires an explicit cast
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

1

A kolega czytać potrafi? Masz tam napisane: *"error C2664: 'fread' : cannot convert parameter 4 from 'void *' to 'FILE '", czyli wystarczy rzutować:

size_t retcode = fread(..., (FILE*)stream);
0

Rzutować próbowałem w stylu C++ i nie działało. Zresztą przy rzutowaniu w stylu C (czyli Twoim sposobem) wyskakuje ( i tu już mi nie zarzucisz braku umiejętności czytania )

1>c:\users\arbuz\documents\visual studio 2010\projects\ftpupload_with_wizard\ftpupload_with_wizard\ftpupload_with_wizard.cpp(51): error C2143: syntax error : missing ')' before ';'
</del>

Pomyliłem nawiasy, już dzisiaj zmęczony jestem . Oczywiście proste rzutowanie działa znakomicie :) A ja chciałem kombinować jak koń pod górę z castami...

Tak w ogóle to nie spodziewałem się kiksa w oficjalnym przykładzie, strasznie niedopracowana ta biblioteka .

0

Kiks jest z twojej strony, bo nie znasz języka programowania, w którym został napisany przykład. A mowa o C, w którym konwersja wskaźnika typu void na jakikolwiek inny następuje automatycznie. W C++, w którym to ty piszesz, tego nie ma i rzutowanie jest potrzebne (i to powinieneś skorzystać z reinterpret_cast).

1 użytkowników online, w tym zalogowanych: 0, gości: 1