views:

383

answers:

2

I'm pretty new to c++ and I'm using libcurl to make an http request and get back a string with the respond's content.

size_t write_to_string(void *ptr, size_t size, size_t count, void *stream) {
    ((std::string*)stream)->append((char*)ptr, 0, size*count);
    return size*count;
}

int main(void) {

    CURL *curl;
    CURLcode res;
    curl = curl_easy_init();

  if (curl) {
    curl_easy_setopt(curl, CURLOPT_URL, "http://www.browsarity.com/");

    std::string response;
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_to_string);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

    res = curl_easy_perform(curl);
    curl_easy_cleanup(curl);

    // The "response" variable should now contain the contents of the HTTP response
  }
  return 0;
}

after running the above code (with VS2005) I get this errors:

1>libcpmtd.lib(xdebug.obj) : error LNK2019: unresolved external symbol __malloc_dbg referenced in function "void * __cdecl operator new(unsigned int,struct std::_DebugHeapTag_t const &,char *,int)" (??2@YAPAXIABU_DebugHeapTag_t@std@@PADH@Z)
1>libcpmtd.lib(xdebug.obj) : error LNK2019: unresolved external symbol __free_dbg referenced in function "void __cdecl operator delete(void *,struct std::_DebugHeapTag_t const &,char *,int)" (??3@YAXPAXABU_DebugHeapTag_t@std@@PADH@Z)
1>libcpmtd.lib(stdthrow.obj) : error LNK2019: unresolved external symbol __CrtDbgReportW referenced in function "void __cdecl std::_Debug_message(wchar_t const *,wchar_t const *,unsigned int)" (?_Debug_message@std@@YAXPB_W0I@Z)

its seems like its a problem with some libraries and I tried adding "msvcrtd.lib" and I still get the error above with additional new errors.

Answer: I changed the Run Time Library from Multi-Threaded (/MT) to Multi-threaded Debug DLL (/MDd).

A: 

std::string generally should not be part of a public interface of a library distributed in binary form (object, static lib, or DLL). But libcurl is pretty intelligently designed, probably the std::string support is provided by an include file (that's ok) which converts things to a portable format before calling into the library.

I think you just need to be careful to link your debug builds with the debug version of libcurl, and your release builds with the release version. Otherwise part of your program wants msvcrt.lib and part wants msvcrtd.lib, and they conflict if you try to use both at once.

EDIT in response to the asker's comment:

There's a dropdown combo box in the compile/build toolbar, that lets you select between Debug and Release configurations.

Also, the Linker "Additional Inputs" setting in the project properties can have different values for Debug and Release. Probably the debug version should use "libcurld.lib" and the release version "libcurl.lib", but not everyone follows that same convention.

If you added the .lib file to your project instead of listing it in the link options, you can still do this by adding both variants and setting "Exclude this file from the build" appropriately. But this looks ugly and will confuse anyone else who works on the project. I would use the Linker options in the project properties.

Ben Voigt
How do I link my dbug builds? using visual studio 2005..
shaimagz
what about changing the std::string into a char * ?
shaimagz
Not sure why std::string should not be part of a public interface. The alternative is char*, which has its own problems.
Ben
@BenVoigt - std::string is not part of the CURL API. It's simply taking a `void *` and passing the pointer unchanged to the write function (where the user code needs to cast it to the correct type).
R Samuel Klatchko
@the other Ben: Because std::string is not standardized at the binary level, so you can't create a std::string in one part of the program and expect another part compiled separately to understand it.
Ben Voigt
@Samuel: you're right -- I hadn't noticed that libcurl sees that as an opaque pointer, but it definitely is following the rule of not trying to share std::string objects across binary library boundaries. So the std::string usage is ok.
Ben Voigt
after you guys helped me understand whats the problem in general i played with the setting a lil and found that I only needed to change my settings to Multi-threaded Debug DLL (/MDd) instead of Multi-threaded (/MT)
shaimagz
and who voted down for this answer??
shaimagz
Please note that you can't distribute the Debug DLL with your program, only the release runtime library DLL. For your release build you should find a release version of libcurl.lib that works with either /MT or /MD.
Ben Voigt
@Ben Voight: I guess I was assuming that all parts of the program are compiled the same way, even though they're compiled separately. But sure, if you can't guarantee that, then you'll run into problems.
Ben
+1  A: 

You would need to download and compile the source code to get your DLLs/Library files. I had the similar debugging and linking problems with binary version I downloaded for VS 2005. Make sure you include the header and library paths in compiler options and to link the libcurl.dll etc. just put it in the working directory or system32 folder.

Dave18
Thanks but I already had the program linked with the libcurl.lib and libcurl.dll files and the includes. I tried to put it in the system32 folder but still nothing.
shaimagz
Did you download and complied the source code and tried linking with those files? I suggest you to download and use the "dependency walker" to figure which DLLs your code is not linked with or if they are of a different version or maybe corrupted.
Dave18