Getting CURL to work with Visual Studio and C

I need some help getting a "hello world" with C and libcurl. I have installed curl on my machine - I'm not sure if I have all of the expected components and headers, though. Any help would be greatly appreciated.
AmyLAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jkrCommented:
What errors are you getting? All you need is 'curl.h' and a 'curllib*.lib' that matches your project configuration.
0
sarabandeCommented:
you may try the following steps:

1. download the Win32 MSVC package for example from http://curl.haxx.se/download.html#Win32.  extract the download to a new folder - say c:\projects\curl.

2. start a new empty win32 console project in Visual Studio. go to
    Project - Project Properties - Configuration Properties - VC++ Directories Include Directories
    add the curl include path to the list of include paths. (c:\projects\curl\include)

3. go to   Project - Project Properties - Configuration Properties - VC++ Directories Library Directories
    add the curl library path to the list of library paths. (c:\projects\curl\lib)

4. go to  Project - Project Properties - Configuration Properties - VC++ Directories Executable Directories
    add the curl dll path to the list of library paths. (the folder where the curl dll's are located). alternatively
    copy the dll's to syswow64 folder in a 64-bit system or to system32 folder if you have a 32-bit windows.

5. if you compile a test program, you may get the message saying libsasl.dll is missing. you will need to download this file and put it in the same directory as the other curl dll's or where your executable is located. you may get libsasl.dll from OpenLDAP for Windows.

6. if you got issues that macros CURL_XXXXX were not defined you may define them in the preprocessor settings of your configuration.

additionally I would switch off 'precompiled header' and use 'multi byte character set'.

Sara
0
AmyLAuthor Commented:
Thank you - this is exactly what I need. I followed your instructions. Here is the build error I am getting at this point:

error LNK2019: unresolved external symbol __imp__curl_global_init referenced in function _wmain

Thanks!
Amy
0
Starting with Angular 5

Learn the essential features and functions of the popular JavaScript framework for building mobile, desktop and web applications.

sarabandeCommented:
error LNK2019: unresolved external symbol __imp__curl_global_init referenced in function _wmain
the curl worked with a global variable probably named '_curl_global_init'.

to get the global variable defined you need to call curl_global_init function called once in your sources. the best place is the main function where you may add the call

//#include <curl/curl.h>
#include <curl.h>

....
int main(int argc, char * argv[])
{
     long flags = CURL_GLOBAL_ALL;
     CURLcode curlcode = curl_global_init(flags ); 
     ...

Open in new window


that should solve the issue.

see also man page for more information:
http://curl.haxx.se/libcurl/c/curl_global_init.html

Sara
0
AmyLAuthor Commented:
Hi!
Thank  you for your continued efforts. I tried adding those lines, but I am still getting the error:
unresolved external symbol __imp__curl_global_init referenced in function _wmain
0
sarabandeCommented:
can you search the headers for a declaration like

external CURLcode _curl_global_init;

or

external CURLcode _imp__curl_global_init;

if found, you would copy that statement and add it above your mainb function without the external.

Sara
0
AmyLAuthor Commented:
I copied these definitions from the header:

CURLcode curl_global_init(long flags);

CURLcode curl_global_init_mem(long flags,
      curl_malloc_callback m,
      curl_free_callback f,
      curl_realloc_callback r,
      curl_strdup_callback s,
      curl_calloc_callback c);

void curl_global_cleanup(void);

I am still getting the linker errors. You probably already know this, but there are a series of these errors in addition to the one that I had referenced earlier. They all appear to be closely related. The top three are:

error LNK2019: unresolved external symbol _curl_easy_init referenced in function _main
error LNK2019: unresolved external symbol _curl_easy_setopt referenced in function _main
error LNK2019: unresolved external symbol _curl_easy_perform referenced in function _main

Thank you!
-Amy
0
sarabandeCommented:
the statements you copied are not the ones I meant.

the curl library uses global variables _imp__curl_global_init, curl_easy_init,  curl_easy_setopt,  curl_easy_perform (perhaps more ...).

these global variables are not defined yet but only declared external. that's why the linker complains. (note, the linker adds an additional _ to the names of the global variables).

there should be a simple possibility to add the definition for all these globals. for example, it might exist a .c file in the curl sources where all globals were defined and you simply have to add the .c file to your project. alternatively, there may be a header file where the definitions were made (note a declaration of a global variable has the specifier 'external' while a definition has not). if so, you would include that header into your main c source and only there to prevent from error of a multiple definition the linker also would complain of.

to go on, you may search for all of the 'unresolved symbols' (without the prefix underscore) in all files *.* below the curl installation folder. if you find a file where the definitions are made you either add it to your project or include it if it as a header file.

if you only find statements with an external keyword, you may copy the statement, paste it above your main function and remove the external.

I will try to download the curl library myself and find out the reasons for your issues.

Sara
0
AmyLAuthor Commented:
Thank you very much. If you are able to include libcurl successfully, that will be a great help to me.
0
sarabandeCommented:
I downloaded the source code of libcurl (since my current environment is not suitable to unzip the library version for windows) and I found from the code that calling

 
CURLcode curlcode = curl_global_init(CURL_GLOBAL_DEFAULT);

Open in new window


once in main before calling any other curl function is sufficient.

that means, the unresolved global symbols are not required by your code but by the library code of curl.

to solve the issue you most likely have to add a library or object file from curl/lib folder where the symbols are defined.

did you already add a library to your project at properties Linker - Input ?

can you post the contents of curl/lib as a screenshot?

Sara
0
AmyLAuthor Commented:
Thank you again for your help. I am attaching a screen shot.
curl-lib-dir.png
0
sarabandeCommented:
are you sure, you downloaded libcurl for windows (win32)?

normally, a packet for windows would provide a lib folder with .lib files as in windows the typical extension for libraries is .lib and not .a.

ok, if it is the right download you have the choice to use either the wrapper functions to the dll variant of libcurl by adding the libraries with extension .dll.a to Linker - Input  - Additional Dependencies. or, if you want to go without the dll's, add the libraries with extension .a (without dll) to your project. it should not matter whether you need all libraries or not. perhaps only adding libcurl.a could be sufficient.

I found out that there is a flag constant CURL_GLOBAL_WIN32 which should be used for initialization.

CURLcode curlcode = curl_global_init(CURL_GLOBAL_WIN32);

Open in new window


Sara
0
AmyLAuthor Commented:
I added all of the .a's into the additional dependencies list, and that seemed to solve the initial linker errors. Now I am getting a few others, such as:
unresolved external symbol ___umoddi3

I'm guessing I need to add another library to the additional dependencies, but I'm not sure which one. It does say that the function is called from libcrypto.
0
sarabandeCommented:
am getting a few others, such as:
 unresolved external symbol ___umoddi3
it is more likely that you need to remove some .a libraries which are not needed for your platform or configuration.

first try to remove libcrypto (if encrypting/decrypting is not one of your main purposes).

if that doesn't work you may try to go only with libcurl.a and use the CURL_GLOBAL_WIN32 flag for curl_global_init.

if there are still unresolved externals, you may add libz.a next, and so on. if a library added doesn't resolve an unresolved external you may remove it, especially if you got more unresolved symbols by it.

if found the following pdf

http://curl.haxx.se/libcurl/c/Using-libcurl-with-SSH-support-in-Visual-Studio-2010.pdf 

which builds the libcurl libraries from scratch rather than using already built ones. even if you don't want to go this way you will find  a sample program and hints how to create folders and add them to your configuration.

Sara
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
AmyLAuthor Commented:
Thank you so much! With some tweaking, it builds and runs now. I just have one last question...
Do you know how to translate a basic authentication that would be used in a curl command line command into the correct options for running it in a C application? For instance, my curl command from a command line looks like:

curl --user [user id] --include --header "Authorization: Basic [password]" "[url]"

In my program, I am doing:

curl_easy_setopt(curl, CURLOPT_URL, [url]);
curl_easy_setopt(curl, CURLOPT_HEADER, "Authorization: Basic [password]");
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (long) CURLAUTH_BASIC);
curl_easy_setopt(curl, CURLOPT_USERPWD, "[password]");

My command line execution is succeeding, but my program returns "Unauthorized".

Thank you so much for your help. It looks like I am nearly out of the woods on this.
0
sarabandeCommented:
I didn't work with curl myself. so I can't help you with the authorization issue.

it might be crucial that you start your program 'as administrator' but that is only a shot from the hip.

perhaps you should try to get the sample program running which was at end of the pdf 'Using-libcurl-with-SSH-support-in-Visual-Studio-2010'.

Sara
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.