c++ - 使用/clr 或 clr :pure (cpprestsdk aka casablanca) 编译时不支持互斥锁

标签 c++ visual-c++ clr cpprest-sdk

我在 visual c++ 中使用 64 位 配置创建了一个 CLR 项目,并尝试使用 cpprestsdk aka casablanca 64bit.

但是当我运行项目时,出现了一个错误:

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 ==========

其他错误:

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

IDE 在 .then 函数中显示有关 '[' 字符的错误,例如 .then([=](http_response response) ,如果您指出它,它会显示 "a local lambda is not allowed in a member function of a managed class"

如果我在具有 64 位配置的 Visual c++ 的 Windows 控制台应用程序 中尝试 cpprestsdk,它工作正常。

我使用的是 visual studio 2017。

你认为cpprestsdk不能用于vc++的CLR项目吗?

谢谢。

这是我的代码,以及我刚从它的教程中得到的关于 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*/

最佳答案

this answer 的最后, Hans Passant 给出了一个对你的情况有用的提示。基本上,您需要一个单独的 c++ 库(clr 支持已关闭),您可以在其中包装 cpprest代码,从您的 CLR 项目链接此库,并确保包含的 header 不会带来 <mutex>中。

举个例子,在restwrapper.h 头文件中有一个这样的类:

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

在其实现文件 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 ...
}

您可以在 DLL 中编译此类(链接 cpprest 及其所有相关库),然后让您的 CLR 项目链接该库。在 CLR 项目中,您只需要包含 restwrapper.h,它又不包含任何内容:

#include <restwrapper.h>
System::Void Testapi_Load(System::Object^  sender, System::EventArgs^  e) 
{
    RestWrapper wrapper;
    wrapper.test();
}

关于c++ - 使用/clr 或 clr :pure (cpprestsdk aka casablanca) 编译时不支持互斥锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49791269/

相关文章:

c++ - 应用程序无法获取命令参数

c++ - Eclipse、C++ 和 Mysql

c++ - 如何从 vector 中删除所有元素

matlab - 将 Matlab 与 C++ 集成

java - 垃圾收集和线程

c++ - 在循环中重新声明 for 循环变量时出错

c++ - MSBuild 构建后步骤

c++ - 静态文本颜色

powershell - 远程运行命令时如何更改Powershell CLR版本?

.net - 单个 .NET 程序集针对两个不同的 CLR?