简体   繁体   中英

Mutex is not supported when compiling with /clr or clr:pure (cpprestsdk aka casablanca)

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*/

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();
}

您可以从CLR项目中调用使用互斥锁的类,您需要做的是创建一个普通的c ++项目并创建具有所需功能但不在其标头中公开<mutex>的类,然后您可以自由调用这些类来自您的CLR项目。

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

Simplest solution really.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM