4

I create a CLR project in visual c++ with 64 bit configuration, and try to use cpprestsdk aka casablanca 64bit.

But when I run the project, an error occured:

1>------ Build started: Project: Timestamp, Configuration: Debug x64 ------
1>MyForm.cpp
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.13.26128\include\mutex(8): fatal error C1189: #error:  <mutex> is not supported when compiling with /clr or /clr:pure.
1>Testapi.cpp
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.13.26128\include\mutex(8): fatal error C1189: #error:  <mutex> is not supported when compiling with /clr or /clr:pure.
1>Generating Code...
1>Done building project "Timestamp.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Other error:

E2093   a local lambda is not allowed in a member function of a managed class   Timestamp   c:\Users\Laptop-attendance\source\repos\Timestamp\Timestamp\Testapi.h   97

The IDE shows an error about '[' characters in the .then function like .then([=](http_response response), which if you pointed it out, it says "a local lambda is not allowed in a member function of a managed class"

If I try the cpprestsdk in a Windows Console Application of Visual c++ with 64 bit configuration, it works fine.

I'm using visual studio 2017.

Do you think cpprestsdk cannot be used in CLR project of vc++?

Thanks.

Here's my code, and the code about cpprestsdk I just got it from its tutorial:

#ifndef TESTAPI_H
#define TESTAPI_H

#pragma once

#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include <cpprest/json.h>

namespace Timestamp {

    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;

    using namespace utility;                    // Common utilities like string conversions
    using namespace web;                        // Common features like URIs.
    using namespace web::http;                  // Common HTTP functionality
    using namespace web::http::client;          // HTTP client features
    using namespace concurrency::streams;       // Asynchronous streams

    /// <summary>
    /// Summary for Testapi
    /// </summary>
    public ref class Testapi : public System::Windows::Forms::Form
    {
    public:
        Testapi(void)
        {
            InitializeComponent();
            //
            //TODO: Add the constructor code here
            //
        }

    protected:
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        ~Testapi()
        {
            if (components)
            {
                delete components;
            }
        }

    private:
        /// <summary>
        /// Required designer variable.
        /// </summary>
        System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        void InitializeComponent(void)
        {
            this->SuspendLayout();
            // 
            // Testapi
            // 
            this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
            this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
            this->ClientSize = System::Drawing::Size(284, 261);
            this->Name = L"Testapi";
            this->Text = L"Testapi";
            this->Load += gcnew System::EventHandler(this, &Testapi::Testapi_Load);
            this->ResumeLayout(false);

        }
#pragma endregion
    private: System::Void Testapi_Load(System::Object^  sender, System::EventArgs^  e) {

        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://13.231.231.252:3000/api/individual_employment_setting/detail/172"));

            // Build request URI and start the request.
            //uri_builder builder(U("/search"));
            //builder.append_query(U("q"), U("cpprestsdk github"));
            return client.request(methods::GET);
        })

            // Handle response headers arriving.
            .then([=](http_response response)
        {
            printf("Received response status code:%u\n", response.status_code());

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

            //show content in console
            printf("Response body: \n %s", buffer.collection().c_str());

            //parse content into a JSON object:
            //json::value jsonvalue = json::value::parse(buffer.collection());

            return  fileStream->print(buffer.collection()); //write to file anyway
        })

            // 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)
        {
            printf("Error exception:%s\n", e.what());
        }

    }
    };
}

#endif /*TESTAPI_H*/
noyruto88
  • 767
  • 2
  • 18
  • 40

3 Answers3

3

You can call a class that uses mutexes from a CLR project, what you need to do is create a normal c++ project and create classes that have the required functionality but don't expose <mutex> in their headers, you are then free to call these classes from your CLR project.

Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
3

At the very end of this answer, Hans Passant gives a hint which is useful in your case. Basically, you need a separate c++ library (clr support turned off) where you wrap the cpprest code, link this library from your CLR project and be sure no included headers will bring <mutex> in.

Just an example, have a class like this, in a restwrapper.h header file:

class RestWrapper
{
public:
    void test();
};

In its implementation file, restwrapper.cpp:

#include "restwrapper.h"

#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include <cpprest/json.h>

using namespace utility;                    // Common utilities like string conversions
using namespace web;                        // Common features like URIs.
using namespace web::http;                  // Common HTTP functionality
using namespace web::http::client;          // HTTP client features
using namespace concurrency::streams;       // Asynchronous streams

void RestWrapper::test()
{
    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://13.231.231.252:3000/api/individual_employment_setting/detail/172"));

        //etc ...
}

You can compile this class in a DLL (linking cpprest and all its related libraries) then make your CLR project link that library. In the CLR project you need to include restwrapper.h only, which in turn includes nothing:

#include <restwrapper.h>
System::Void Testapi_Load(System::Object^  sender, System::EventArgs^  e) 
{
    RestWrapper wrapper;
    wrapper.test();
}
Emmanuel DURIN
  • 4,803
  • 2
  • 28
  • 53
p-a-o-l-o
  • 9,807
  • 2
  • 22
  • 35
  • Thanks sir, I will try it. – noyruto88 Apr 12 '18 at 09:59
  • About the (linking cpprest and all its related libraries), do i need to manually link it in the project? – noyruto88 Apr 13 '18 at 05:36
  • Hi sir, I'm having an "entry point" error. What entry point should i set in DLL project? In my source files i have, dllmain.cpp, MyCpprestDll.cpp, stdafx.cpp (this three are generated by IDE), and the last one that I added, RestWrapper.cpp. But if i set entry point in the properties, I get many errors. – noyruto88 Apr 13 '18 at 06:09
  • Good morning @noyruto88. I'm sorry I cannot be of any help today, but you can make a new question out of this issue and there will be plenty of people eaging to answer it. Thanks. – p-a-o-l-o Apr 13 '18 at 06:31
  • Ok Sir, Thank you. – noyruto88 Apr 13 '18 at 06:35
  • Hi Sir, do you have idea about this? https://stackoverflow.com/questions/49868625/http-client-of-cpprestsdk-casablanca – noyruto88 Apr 17 '18 at 05:25
  • Hi Sir @paolo. I posted a question about japanese charaters in c++. Maybe you can help. Thank you. https://stackoverflow.com/questions/51204412/dealing-with-kanji-characters-in-c – noyruto88 Jul 06 '18 at 07:20
-5

Just right click your .cpp file, and under "General -> Common Language Runtime Support" select "No Common Language RunTime Support".

Simplest solution really.

Mecanik
  • 1,539
  • 1
  • 20
  • 50
  • 1
    it's not a solution when one needs CLR (for interacting with .NET or wrapping C# functions for example) – phuclv Sep 16 '20 at 10:36
  • 1
    Yes it is, solved the same issue this way recently. In fact one is able to supply a different compiler options set for each c++ file included in project, that is - to combine pure C++ and C++/CLI source files inside one project. The next step is likely to utilize PIMPL idiom in order to make a kind of wrapper in raw C++ above problem class - so that all dangerous includes are included in c++ file. The last step is to include wrapper header in C++/CLI source file (compiled with different options). I personally had to disable C++/CLI for project and _enable_ it only for desired files. – n0ne Dec 12 '20 at 16:36
  • Wondering why the down votes since the suggestion is to turn of /clr for the SINGLE .cpp file..... Do not understand why the recommendation for a completely different project is preferred... – David V. Corbin Oct 05 '22 at 12:11