microsoft / cpprestsdk

The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design. This project aims to help C++ developers connect to and interact with services.
Other
8.01k stars 1.66k forks source link

Using Cpprestsdk with /permissive- in VS2017? #605

Open DragonOsman opened 6 years ago

DragonOsman commented 6 years ago

When trying to compile the app shown in the Getting Started Intro article for Cpprestsdk with the /permissive- compiler switch on, I got these error messages:

1>c:\vcpkg\packages\cpprestsdk_x86-windows\include\cpprest\streams.h(890): error C2187: syntax error: 'identifier' was unexpected here 1>c:\vcpkg\packages\cpprestsdk_x86-windows\include\cpprest\streams.h(1123): note: see reference to class template instantiation 'Concurrency::streams::basic_istream' being compiled 1>c:\vcpkg\packages\cpprestsdk_x86-windows\include\cpprest\http_msg.h(571): error C2039: 'to_utf16string': is not a member of 'global namespace'' 1>c:\vcpkg\packages\cpprestsdk_x86-windows\include\cpprest\http_msg.h(571): error C3861: 'to_utf16string': identifier not found 1>c:\vcpkg\packages\cpprestsdk_x86-windows\include\cpprest\http_msg.h(981): error C2039: 'to_utf16string': is not a member of 'global namespace'' 1>c:\vcpkg\packages\cpprestsdk_x86-windows\include\cpprest\http_msg.h(981): error C3861: 'to_utf16string': identifier not found 1>c:\vcpkg\packages\cpprestsdk_x86-windows\include\cpprest\http_msg.h(1210): error C2039: 'to_utf16string': is not a member of 'global namespace'' 1>c:\vcpkg\packages\cpprestsdk_x86-windows\include\cpprest\http_msg.h(1210): error C3861: 'to_utf16string': identifier not found 1>c:\vcpkg\packages\cpprestsdk_x86-windows\include\cpprest\http_client.h(606): error C2039: 'to_utf16string': is not a member of 'global namespace'' 1>c:\vcpkg\packages\cpprestsdk_x86-windows\include\cpprest\http_client.h(606): error C3861: 'to_utf16string': identifier not found 1>Done building project "rest_app1.vcxproj" -- FAILED. ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

I also have a warning about /sdl vs. /gs-, minus but that doesn't matter here.

And removing the /permissive- allows the code to compile, but when I run it, I get the following unhandled exception in xmemory0 in the function _Deallocate():

Unhandled exception at 0x51C9CAB6 (ucrtbased.dll) in rest_app1.exe: An invalid parameter was passed to a function that considers invalid parameters fatal.

So I need help with fixing the exception error and also with getting the /permissive- flag to work with the Cpprestsdk. Thanks in advance for any help.

Edit: Here's my code:

// Osman Zakir
// 11 / 1 / 2017
// cpprestsdk, Casablanca Getting Started Tutorial application
// taking a look at how to use our http_client to connect to a server and download some data

#include <iostream>
#include <cpprest\http_client.h>
#include <cpprest\filestream.h>

using namespace utility;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace concurrency::streams;

int main(int argc, char* argv[])
{
    auto fileStream = std::make_shared<ostream>();

    // Open stream to output file.
    pplx::task<void> requestTask = fstream::open_ostream(U("results.html")).then([=](ostream outFile)
    {
        *fileStream = outFile;

        // Create http_client to send the request.
        http_client client(U("http://www.bing.com/"));

        // Build request URI and start the request.
        uri_builder builder;
        try
        {
            uri_builder builder{ U("/search") };
        }
        catch (const std::invalid_argument &e)
        {
            std::cerr << "Invalid argument error: " << e.what() << '\n';
        }
        catch (const std::exception &e)
        {
            std::cerr << "Exception error: " << e.what() << '\n';
        }
        catch (...)
        {
            std::cerr << "Unknown excepton occured\n";
        }
        builder.append_query(U("q"), U("cpprestsdk github"));
        return client.request(methods::GET, builder.to_string());
    })

        // Handle response headers arriving.
        .then([=](http_response response)
    {
        std::cout << "Received response status code: " << response.status_code();

        // Write response body into the file.
        return response.body().read_to_end(fileStream->streambuf());
    })

        // Close the file stream.
        .then([=](size_t)
    {
        return fileStream->close();
    });

    // Wait for all the outstanding I/O to complete and handle any exceptions
    try
    {
        requestTask.wait();
    }
    catch (const std::exception &e)
    {
        std::cout << "Error exception: " << e.what() << '\n';
    }
}

As you can see, I tried to catch a std::invalid_argument exception. That didn't help, though. So what should I do?

juanchopanza commented 5 years ago

FWIW I am seeing this in version 2.10.13:

.../cpprest/http_msg.h(716): error C2039: 'to_utf16string': is not a member of '`global namespace''
.../cpprest/http_msg.h(716): error C3861: 'to_utf16string': identifier not found

The error seems to be coming from the default value of the second function parameter here in cpprest/http_msg.h:

     void set_body(const utf16string& body_text,                                                                                 
                   utf16string content_type = utility::conversions::to_utf16string("text/plain"))         

The same error occurs at least in two other places in that file.