简体   繁体   English

使用/ clr或clr:pure编译时​​不支持Mutex(cpprestsdk aka casablanca)

[英]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 . 我在visual c++使用64 bit配置创建了一个CLR project ,并尝试使用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" IDE在.then函数(如.then([=](http_response response)显示有关'['字符的错误,如果您指出该错误,则说"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. 如果我在具有64位配置的Visual c ++的Windows Console Application中尝试cpprestsdk ,则可以正常工作。

I'm using visual studio 2017. 我正在使用Visual Studio 2017。

Do you think cpprestsdk cannot be used in CLR project of vc++? 您认为cpprestsdk不能在vc ++的CLR项目中使用吗?

Thanks. 谢谢。

Here's my code, and the code about cpprestsdk I just got it from its tutorial: 这是我的代码,以及有关cpprestsdk的代码,我只是从其教程中获得的:

#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. 回答的最后 ,汉斯·帕桑特(Hans Passant)给出了一个提示,对您的情况很有用。 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. 基本上,您需要一个单独的c ++库(关闭了cpprest支持),在其中包装cpprest代码,从CLR项目链接此库,并确保没有包含的标头会引入<mutex>

Just an example, have a class like this, in a restwrapper.h header file: 只是一个例子,在restwrapper.h头文件中有一个这样的类:

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

In its implementation file, restwrapper.cpp : 在其实现文件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. 您可以在DLL中编译此类(链接cpprest及其所有相关的库),然后使CLR项目链接该库。 In the CLR project you need to include restwrapper.h only, which in turn includes nothing: 在CLR项目中,您仅需要包含restwrapper.h ,而后者不包含任何内容:

#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". 只需右键单击您的.cpp文件,然后在“常规->公共语言运行时支持”下选择“无公共语言运行时支持”。

Simplest solution really. 真正最简单的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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