问题
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*/
回答1:
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();
}
回答2:
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.
回答3:
Just right click your .cpp file, and under "General -> Common Language Runtime Support" select "No Common Language RunTime Support".
Simplest solution really.
来源:https://stackoverflow.com/questions/49791269/mutex-is-not-supported-when-compiling-with-clr-or-clrpure-cpprestsdk-aka-casa