2021년 신규 작성 

C++ REST SDK(cpprestsdk) Sample

 

C++ REST SDK(cpprestsdk) Sample

Introduction https://github.com/Microsoft/cpprestsdk Microsoft에서 만든 클라이언트, 서버용 C++ HTTP 통신 모듈이며, JSON URI, 비동기, 웹소켓, oAuth 등을 지원 C++11의 비동기, 병렬 프로그램 모델 지원 크로스 플랫

cdecl.github.io

--

 

https://casablanca.codeplex.com/

 

The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design. This project aims to help C++ developers connect to and interact with services.

 

What's in the SDK:

  • Features - HTTP client/server, JSON, URI, asynchronous streams, WebSockets client, oAuth
  • PPL Tasks - A powerful model for composing asynchronous operations based on C++ 11 features
  • Platforms - Windows desktop, Windows Store, Windows Phone, Ubuntu, OS X, iOS, and Android
  • Support for Visual Studio 2012, 2013, and 2015 with debugger visualizers
  • NuGet package with binaries for Windows and Android platforms

 

- Microsoft에서 만든 클라이언트, 서버용 C++ HTTP 통신 모듈이며, JSON URI, 비동기, 웹소켓, oAuth 등을 지원 

- C++11의 비동기, 병렬 프로그램 모델 지원

- 크로스 플랫폼 지원 등..

- XML 파서도 지원 해줬으면 하는 아쉬움이...

 

 

# 설치방법

https://casablanca.codeplex.com/documentation

- openssl 및 boost 라이브러리 필요 

- 리눅스(g++)는 소스를 다운 받아 CMake를 이용하여 make 파일 생성, 빌드 및 설치 

  ** 설치시 Release/include/cpprest/details/http_constants.dat 파일이 누락이 되어 수동으로 복사 해줌 (Ubuntu 14.04)

- 윈도우(VC++)는 프로젝트 파일 포함, VS로 열어서 컴파일 하면 됨. 

  그러나 그냥 Nuget 패키지로 설치하면 바이너리와 include 파일을 쉽게 받음.

- 기본적으로 동적 링크(dll, so) 파일로 생성 

 

 

# 간단 예제 소스 

- U("") 는 _T("") 와 비슷한, UNICODE 및 MBCS 환경의 문자열 타입을 스위칭 해주는 매크로. 

  허나 U는 _T와는 다르게 _WIN32 환경이면 기본으로 _UTF16_STRINGS으로 정의되어 있어 프로젝트의 문자집합의 세팅과 관계 없이 UNICODE와 같은 환경으로 동작 

  리눅스 환경에서는 다른 설정을 해주지 않는 이상 char, std::string으로 정의 

utility::string_t은 std::string과 std::wstring을 스위칭 해주는 타입 

- 대체적인 패턴은, 동기는 .get(), 비동기는 then().wait() 조합으로 사용

 

 

#include <iostream>
using namespace std;
 
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
 
#pragma comment(lib, "cpprest120_2_4") // windows only
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 GetHttp()
{
http_client client(U("http://en.cppreference.com/w/"));
auto resp = client.request(U("GET")).get();
 
wcout << U("STATUS : ") << resp.status_code() << endl;
wcout << "content-type : " << resp.headers().content_type() << endl;
wcout << resp.extract_string(true).get() << endl;
}
 
void GetHttpAsync()
{
http_client client(U("http://en.cppreference.com/w/"));
 
client.request(U("GET")).then([](http_response resp){
wcout << U("STATUS : ") << resp.status_code() << endl;
wcout << "content-type : " << resp.headers().content_type() << endl;
 
resp.extract_string(true).then([](string_t sBoby){
wcout << sBoby << endl;
}).wait();
 
}).wait();
 
}
 
 
void GetJson()
{
http_client client(U("http://date.jsontest.com/"));
 
http_request req(methods::GET);
 
client.request(req).then([=](http_response r){
wcout << U("STATUS : ") << r.status_code() << endl;
wcout << "content-type : " << r.headers().content_type() << endl;
 
//{
// "time": "11:25:23 AM",
// "milliseconds_since_epoch" : 1423999523092,
// "date" : "02-15-2015"
//}
 
r.extract_json(true).then([](json::value v) {
wcout << v.at(U("date")).as_string() << endl;
wcout << v.at(U("time")).as_string() << endl;
}).wait();
 
}).wait();
 
}
 
int main(int argc, char* argv[])
{
wcout.imbue(locale("kor")); // windows only
 
GetHttp();
GetHttpAsync();
GetJson();
 
return 0

}

 

 

C++0x RValue Reference 라는것이 추가 되었다.


RValue Reference는  Move semantics와 Perfect forwarding 이라는 두가지 기능을 가진다.


1. Move semantics

기존 부터 있던 Reference는 LValue Reference 라고 불린다.

int n = 10;
int &r = n;  // LValue Reference
int *p = &n;  // 포인터 참조 방식
cout << r << " " << *p << endl;

C++의 참조는 내부적으로 포인터를 사용하여 참조를 하게 되지만 사용함에 있어 보다 우아하게(?) 사용을 할 수 있다는 장점이 있다.


반면 RValue Reference는 아래와 같이 사용한다.

int n = 10;
int &&r =n; // 그런데 기존 참조랑 머가 틀리냐??

int, long 등의 기본 타입과 기존 클래스의 복사생성자, 대입연산자에 대해서는 RValue Reference 참조는 기존 Value Reference와 똑같이 동작을 한다.

하지만 RValue Reference는 객체(변수)의 주소를 참조하는 기존의 LValue Reference와 틀리게,
RValue Reference 로 겹지정한 복사생성자 및 대입연산자를 따로 구현, 그리고 그것을 의도적으로 호출하게 할 수 있다.

그리고 그 RValue Reference 로 겹지정한 복사생성자 및 대입연산자에는,
임시객체애 대해서 복사가 아닌  메모리를 이동 (Move) 하는 방법으로 임시 객체의 생성및 소멸에 대한 비용을 줄이는 구현이가능해 진것이다.

소유권 이전 기법을 사용하는 auto_ptr 처럼..



class Item
{
  public:
    Item() : p(new char[100]) {}
    Item(const Item &t) : p(new char[100]) {  memcpy(p, t.p);  } // 복사생성자
    Item(Item &&t) : p(t.p) { t.p = NULL;  } // Move 생성자

    // Item& operator=(const Item &t) { return *this; } // 대입연산자
    // Item& operator=(Item &&t) { return *this; } // Move 대입 연산자
    // ...
   ~Item() { if (p) delete p; }
  
  private:
    char *p;
};

Item&& foo()
{
  Item item;
  // ...
  return item;
}

int main()
{
  Item item;
  Item t = item; // 복사생성자 호출
  Item &r = item; // 참조

  Item &&rr = Item; // 참조
  Item &&mv = std::move(item);  // Move 생성자
  Item &&mvt = foo(); // // Move 생성자
}

위의 코드와 같이 foo() 함수에서 RValue Reference로 리턴을 하게 되면,
Item 객체의 RValue Reference 버전의 Move 생성자가 호출되고
Move 생성자에서 내부 멤버인 포인터의 소유권을 이전하여 임시객체에 대해서 필요 없는 생성-소멸의 과정을 거치지 않게끔 할 수 있는것이다.

그리고 강제로 Move 생성자, Move 대입 연산자를 호출 하기 위해서 std::move() 함수를  이용 할 수도 있다.


C++0x 의 STL에는 RValue Reference 의 코드가 적용 되어 있어 사용하는 것 만으로도 성능 효과를 볼 수가 있다고 한다.
대략 다음과 같은 코드..

std::string s = "s";
std::string str;
str = s + "t" + "r" + "i" + "g";  // 임시객체 (RValue Reference) 사용



2. Perfect forwarding

template 의 내부 함수가 참조 및 상수의 값을 파라미터로 받을 경우 관련되서 여러 개의 버전 구현을 해야하는 문제를,
RValue Reference의 문법으로 하나로 처리 하는 내용.
(자세한 내용은 아래링크 -_-; )



참고 : http://blogs.msdn.com/vcblog/archive/2009/02/03/rvalue-references-c-0x-features-in-vc10-part-2.aspx


'Dev > C++' 카테고리의 다른 글

boost::asio 클라이언트 소켓 (timeout 기능)  (0) 2010.10.14
이미지 변환 모듈 (모바일용, GDI+)  (0) 2010.06.22
C++0x Lambda  (0) 2009.05.20
C++0x 지원 컴파일러 목록  (0) 2009.05.20
C++ Refactoring  (0) 2009.04.14
아래 링크의 글 중 Herb Sutter 의 Lambda 예제 및 설명에 관한 리플..
http://herbsutter.wordpress.com/2008/03/29/trip-report-februarymarch-2008-iso-c-standards-meeting/

[]와 []안에 들어가는 내용에 대해서 명쾌하게 설명을..




Herb Sutter

Re binders: Okay, I give! I’ll use a better example next time.

(no name) asked: "How are local variables captured?" You have to specify whether it’s by copy or by reference. So this example is illegal because it tries to use a local variable:

    int numWidgets = 0;
    for_each( v.begin(), v.end(), []( Widget& w )
    {
        ++numWidgets;  // error, numWidgets is not in scope
    } );

If you want to update numWidgets directly, capture it by reference:

    for_each( v.begin(), v.end(), [&numWidgets]( Widget& w )
    {
        ++numWidgets;  // increments original numWidgets
    } );
    // numWidgets == v.size() here

Or use the shorthand [&] to take all captured variables implicitly by reference:

    for_each( v.begin(), v.end(), [&]( Widget& w )
    {
        ++numWidgets;  // increments original numWidgets
    } );
    // numWidgets == v.size() here

What if you want a local copy? You say to pass it by value, but for safety reasons the current proposal says you get a read-only copy that you can’t modify:

    for_each( v.begin(), v.end(), [numWidgets]( Widget& w )
    {
        int i = numWidgets; // ok
        ++i;
        // "++numWidgets;" would be an error
    } );
    // numWidgets == 0 here

Or use the shorthand [=] to take all captured variables implicitly by copy:

    for_each( v.begin(), v.end(), [=]( Widget& w )
    {
        int i = numWidgets; // ok
        ++i;
        // "++numWidgets;" would be an error
    } );
    // numWidgets == 0 here

Similarly, for the question: "What will happen in the following case:"

    int flag = 0;
    mypool.run( [] { flag = 1; } );
    cout << flag << endl;

The answer is that the code is illegal, you have to say whether you capture flag by value or by reference, which can be as simple as replacing [] with [=] or [&]. And if you capture by value, you get a read-only copy so you couldn’t assign to it.


'Dev > C++' 카테고리의 다른 글

이미지 변환 모듈 (모바일용, GDI+)  (0) 2010.06.22
C++0x, RValue Reference  (0) 2009.05.27
C++0x 지원 컴파일러 목록  (0) 2009.05.20
C++ Refactoring  (0) 2009.04.14
An Overview of the Coming C++ (C++0x) Standard  (0) 2008.12.29

'Dev > C++' 카테고리의 다른 글

C++0x, RValue Reference  (0) 2009.05.27
C++0x Lambda  (0) 2009.05.20
C++ Refactoring  (0) 2009.04.14
An Overview of the Coming C++ (C++0x) Standard  (0) 2008.12.29
asio C++ library  (0) 2008.08.22




C++ 0x에 대한 리뷰 동영상인가 보다.

시간있을때 하나씩 정리를 해볼까 하는데.. 움..

'Dev > C++' 카테고리의 다른 글

C++0x 지원 컴파일러 목록  (0) 2009.05.20
C++ Refactoring  (0) 2009.04.14
asio C++ library  (0) 2008.08.22
C++ 0x - Herb Sutter의 블로그 글  (0) 2008.07.29
C++ 0x  (0) 2008.05.09

'Dev > C++' 카테고리의 다른 글

Unhandled C++ Exceptions  (0) 2007.06.19
OutputDebugString  (0) 2007.05.23
GRETA  (0) 2007.05.14
A non-type template-parameter  (0) 2007.05.14
Member template specialization  (0) 2007.05.14

+ Recent posts