├── Clients ├── DotNetClient_Console │ ├── App.config │ ├── DotNetClient_Console.csproj │ ├── Program.cs │ └── Properties │ │ └── AssemblyInfo.cs └── HtppClient │ ├── HtppClient.cpp │ ├── HtppClient.vcxproj │ ├── ReadMe.txt │ ├── stdafx.cpp │ ├── stdafx.h │ └── targetver.h ├── DllCall.sln ├── Lib └── Connector │ ├── Connector.cpp │ ├── Connector.h │ ├── Connector.vcxproj │ ├── Exports.def │ ├── ReadMe.txt │ ├── dllmain.cpp │ ├── packages.config │ ├── stdafx.cpp │ ├── stdafx.h │ └── targetver.h └── README.md /Clients/DotNetClient_Console/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Clients/DotNetClient_Console/DotNetClient_Console.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {4A2C892E-B840-4FDA-A0A7-14282D78BD7D} 8 | Exe 9 | Properties 10 | DotNetClient_Console 11 | DotNetClient_Console 12 | v4.5.2 13 | 512 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | true 37 | bin\x64\Debug\ 38 | DEBUG;TRACE 39 | full 40 | x64 41 | prompt 42 | MinimumRecommendedRules.ruleset 43 | true 44 | 45 | 46 | bin\x64\Release\ 47 | TRACE 48 | true 49 | pdbonly 50 | x64 51 | prompt 52 | MinimumRecommendedRules.ruleset 53 | true 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 79 | -------------------------------------------------------------------------------- /Clients/DotNetClient_Console/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.InteropServices; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace DotNetClient_Console 9 | { 10 | [UnmanagedFunctionPointer(CallingConvention.StdCall, 11 | CharSet=CharSet.Unicode)] 12 | public delegate void OnCompletedDelegate(string json); 13 | 14 | class Program 15 | { 16 | [DllImport(@"Connector.dll", 17 | EntryPoint = "GetJson", 18 | CallingConvention = CallingConvention.StdCall, 19 | CharSet=CharSet.Unicode)] 20 | private static extern void GetJson(string webServerUrl, [MarshalAs(UnmanagedType.FunctionPtr)] OnCompletedDelegate dlg); 21 | 22 | static void Main(string[] args) 23 | { 24 | string url = "http://date.jsontest.com/"; 25 | OnCompletedDelegate del = new OnCompletedDelegate(OnCompleted); 26 | GetJson(url, del); 27 | Console.ReadLine(); 28 | } 29 | 30 | static void OnCompleted(string json) 31 | { 32 | Console.WriteLine(json); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Clients/DotNetClient_Console/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DotNetClient_Console")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DotNetClient_Console")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("173ca730-0ff5-40d1-ad8a-95f098eeaa2c")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Clients/HtppClient/HtppClient.cpp: -------------------------------------------------------------------------------- 1 | // HtppClient.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | 6 | using namespace std; 7 | using namespace app; 8 | 9 | namespace client 10 | { 11 | void on_completed(const wchar_t* result) 12 | { 13 | wcout << result << endl; 14 | } 15 | } 16 | 17 | int _tmain(int argc, _TCHAR* argv[]) 18 | { 19 | HINSTANCE hInst = LoadLibrary(_T("Connector.dll")); 20 | if(hInst == nullptr) 21 | { 22 | wcout << "Could not find Library!" << endl; 23 | return 1; 24 | } 25 | 26 | vector
headers = { 27 | { L"key_1", L"val_1" }, 28 | { L"key_2", L"val_2" }, 29 | { L"key_3", L"val_3" }, 30 | { L"key_4", L"val_4" } 31 | }; 32 | function callback = client::on_completed; 33 | const wstring webServer = L"http://date.jsontest.com/"; 34 | unique_ptr client = make_unique(); 35 | client->GetJson(webServer, headers, client::on_completed); 36 | system("PAUSE"); 37 | return 0; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /Clients/HtppClient/HtppClient.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {4E3E85F5-3C7D-44CD-A0B6-5E1B02CDE8C4} 23 | Win32Proj 24 | HtppClient 25 | 26 | 27 | 28 | Application 29 | true 30 | v120 31 | Unicode 32 | 33 | 34 | Application 35 | true 36 | v120 37 | Unicode 38 | 39 | 40 | Application 41 | false 42 | v120 43 | true 44 | Unicode 45 | 46 | 47 | Application 48 | false 49 | v120 50 | true 51 | Unicode 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | true 71 | .\Debug 72 | 73 | 74 | true 75 | 76 | 77 | false 78 | .\Release 79 | 80 | 81 | false 82 | 83 | 84 | 85 | Use 86 | Level3 87 | Disabled 88 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 89 | true 90 | 91 | 92 | Console 93 | true 94 | 95 | 96 | XCOPY "$(ProjectDir)cpprest120d_2_4.dll" "$(TargetDir)" /Y 97 | Copying Casablanca DLL to Target directory 98 | 99 | 100 | 101 | 102 | Use 103 | Level3 104 | Disabled 105 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 106 | true 107 | 108 | 109 | Console 110 | true 111 | 112 | 113 | XCOPY "$(ProjectDir)cpprest120d_2_4.dll" "$(TargetDir)" /Y 114 | Copying Casablanca DLL to Target directory 115 | 116 | 117 | 118 | 119 | Level3 120 | Use 121 | MaxSpeed 122 | true 123 | true 124 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 125 | true 126 | 127 | 128 | Console 129 | true 130 | true 131 | true 132 | %(AdditionalDependencies) 133 | 134 | 135 | XCOPY "$(ProjectDir)cpprest120d_2_4.dll" "$(TargetDir)" /Y 136 | Copying Casablanca DLL to Target directory 137 | 138 | 139 | 140 | 141 | Level3 142 | Use 143 | MaxSpeed 144 | true 145 | true 146 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 147 | true 148 | 149 | 150 | Console 151 | true 152 | true 153 | true 154 | %(AdditionalDependencies) 155 | 156 | 157 | XCOPY "$(ProjectDir)cpprest120d_2_4.dll" "$(TargetDir)" /Y 158 | Copying Casablanca DLL to Target directory 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | Create 172 | Create 173 | Create 174 | Create 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | -------------------------------------------------------------------------------- /Clients/HtppClient/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | CONSOLE APPLICATION : HtppClient Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this HtppClient application for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your HtppClient application. 9 | 10 | 11 | HtppClient.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | HtppClient.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | HtppClient.cpp 25 | This is the main application source file. 26 | 27 | ///////////////////////////////////////////////////////////////////////////// 28 | Other standard files: 29 | 30 | StdAfx.h, StdAfx.cpp 31 | These files are used to build a precompiled header (PCH) file 32 | named HtppClient.pch and a precompiled types file named StdAfx.obj. 33 | 34 | ///////////////////////////////////////////////////////////////////////////// 35 | Other notes: 36 | 37 | AppWizard uses "TODO:" comments to indicate parts of the source code you 38 | should add to or customize. 39 | 40 | ///////////////////////////////////////////////////////////////////////////// 41 | -------------------------------------------------------------------------------- /Clients/HtppClient/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // HtppClient.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /Clients/HtppClient/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | #define DEBUG 8 | #define UNICODE 9 | #include "targetver.h" 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include "..\..\Lib\Connector\Connector.h" 19 | 20 | #ifdef DEBUG 21 | #pragma comment(lib, "../../Lib/Connector/Debug/Connector.lib") 22 | #else 23 | #pragma comment(lib, "../../Lib/Connector/Release/Connector.lib") 24 | #endif 25 | -------------------------------------------------------------------------------- /Clients/HtppClient/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /DllCall.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Lib", "Lib", "{1BFF9E60-8285-4FC6-8131-E61A5D9719FB}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Clients", "Clients", "{49BC71AC-23B9-4570-B8AB-B3DA4DC986D8}" 9 | EndProject 10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Connector", "Lib\Connector\Connector.vcxproj", "{BDF69573-3578-4F32-AF57-2E8CF4A42FA8}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetClient_Console", "Clients\DotNetClient_Console\DotNetClient_Console.csproj", "{4A2C892E-B840-4FDA-A0A7-14282D78BD7D}" 13 | EndProject 14 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HtppClient", "Clients\HtppClient\HtppClient.vcxproj", "{4E3E85F5-3C7D-44CD-A0B6-5E1B02CDE8C4}" 15 | EndProject 16 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{108BA514-FC48-44ED-89BC-22F04E6D6CAA}" 17 | ProjectSection(SolutionItems) = preProject 18 | README.md = README.md 19 | EndProjectSection 20 | EndProject 21 | Global 22 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 23 | Debug|Any CPU = Debug|Any CPU 24 | Debug|Mixed Platforms = Debug|Mixed Platforms 25 | Debug|Win32 = Debug|Win32 26 | Debug|x64 = Debug|x64 27 | Release|Any CPU = Release|Any CPU 28 | Release|Mixed Platforms = Release|Mixed Platforms 29 | Release|Win32 = Release|Win32 30 | Release|x64 = Release|x64 31 | EndGlobalSection 32 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 33 | {BDF69573-3578-4F32-AF57-2E8CF4A42FA8}.Debug|Any CPU.ActiveCfg = Debug|Win32 34 | {BDF69573-3578-4F32-AF57-2E8CF4A42FA8}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 35 | {BDF69573-3578-4F32-AF57-2E8CF4A42FA8}.Debug|Mixed Platforms.Build.0 = Debug|Win32 36 | {BDF69573-3578-4F32-AF57-2E8CF4A42FA8}.Debug|Win32.ActiveCfg = Debug|Win32 37 | {BDF69573-3578-4F32-AF57-2E8CF4A42FA8}.Debug|Win32.Build.0 = Debug|Win32 38 | {BDF69573-3578-4F32-AF57-2E8CF4A42FA8}.Debug|x64.ActiveCfg = Debug|x64 39 | {BDF69573-3578-4F32-AF57-2E8CF4A42FA8}.Release|Any CPU.ActiveCfg = Release|Win32 40 | {BDF69573-3578-4F32-AF57-2E8CF4A42FA8}.Release|Mixed Platforms.ActiveCfg = Release|Win32 41 | {BDF69573-3578-4F32-AF57-2E8CF4A42FA8}.Release|Mixed Platforms.Build.0 = Release|Win32 42 | {BDF69573-3578-4F32-AF57-2E8CF4A42FA8}.Release|Win32.ActiveCfg = Release|Win32 43 | {BDF69573-3578-4F32-AF57-2E8CF4A42FA8}.Release|Win32.Build.0 = Release|Win32 44 | {BDF69573-3578-4F32-AF57-2E8CF4A42FA8}.Release|x64.ActiveCfg = Release|x64 45 | {BDF69573-3578-4F32-AF57-2E8CF4A42FA8}.Release|x64.Build.0 = Release|x64 46 | {4A2C892E-B840-4FDA-A0A7-14282D78BD7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 47 | {4A2C892E-B840-4FDA-A0A7-14282D78BD7D}.Debug|Any CPU.Build.0 = Debug|Any CPU 48 | {4A2C892E-B840-4FDA-A0A7-14282D78BD7D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 49 | {4A2C892E-B840-4FDA-A0A7-14282D78BD7D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 50 | {4A2C892E-B840-4FDA-A0A7-14282D78BD7D}.Debug|Win32.ActiveCfg = Debug|Any CPU 51 | {4A2C892E-B840-4FDA-A0A7-14282D78BD7D}.Debug|x64.ActiveCfg = Debug|x64 52 | {4A2C892E-B840-4FDA-A0A7-14282D78BD7D}.Release|Any CPU.ActiveCfg = Release|Any CPU 53 | {4A2C892E-B840-4FDA-A0A7-14282D78BD7D}.Release|Any CPU.Build.0 = Release|Any CPU 54 | {4A2C892E-B840-4FDA-A0A7-14282D78BD7D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 55 | {4A2C892E-B840-4FDA-A0A7-14282D78BD7D}.Release|Mixed Platforms.Build.0 = Release|Any CPU 56 | {4A2C892E-B840-4FDA-A0A7-14282D78BD7D}.Release|Win32.ActiveCfg = Release|Any CPU 57 | {4A2C892E-B840-4FDA-A0A7-14282D78BD7D}.Release|x64.ActiveCfg = Release|x64 58 | {4A2C892E-B840-4FDA-A0A7-14282D78BD7D}.Release|x64.Build.0 = Release|x64 59 | {4E3E85F5-3C7D-44CD-A0B6-5E1B02CDE8C4}.Debug|Any CPU.ActiveCfg = Debug|Win32 60 | {4E3E85F5-3C7D-44CD-A0B6-5E1B02CDE8C4}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 61 | {4E3E85F5-3C7D-44CD-A0B6-5E1B02CDE8C4}.Debug|Mixed Platforms.Build.0 = Debug|Win32 62 | {4E3E85F5-3C7D-44CD-A0B6-5E1B02CDE8C4}.Debug|Win32.ActiveCfg = Debug|Win32 63 | {4E3E85F5-3C7D-44CD-A0B6-5E1B02CDE8C4}.Debug|Win32.Build.0 = Debug|Win32 64 | {4E3E85F5-3C7D-44CD-A0B6-5E1B02CDE8C4}.Debug|x64.ActiveCfg = Debug|x64 65 | {4E3E85F5-3C7D-44CD-A0B6-5E1B02CDE8C4}.Debug|x64.Build.0 = Debug|x64 66 | {4E3E85F5-3C7D-44CD-A0B6-5E1B02CDE8C4}.Release|Any CPU.ActiveCfg = Release|Win32 67 | {4E3E85F5-3C7D-44CD-A0B6-5E1B02CDE8C4}.Release|Mixed Platforms.ActiveCfg = Release|Win32 68 | {4E3E85F5-3C7D-44CD-A0B6-5E1B02CDE8C4}.Release|Mixed Platforms.Build.0 = Release|Win32 69 | {4E3E85F5-3C7D-44CD-A0B6-5E1B02CDE8C4}.Release|Win32.ActiveCfg = Release|Win32 70 | {4E3E85F5-3C7D-44CD-A0B6-5E1B02CDE8C4}.Release|Win32.Build.0 = Release|Win32 71 | {4E3E85F5-3C7D-44CD-A0B6-5E1B02CDE8C4}.Release|x64.ActiveCfg = Release|x64 72 | {4E3E85F5-3C7D-44CD-A0B6-5E1B02CDE8C4}.Release|x64.Build.0 = Release|x64 73 | EndGlobalSection 74 | GlobalSection(SolutionProperties) = preSolution 75 | HideSolutionNode = FALSE 76 | EndGlobalSection 77 | GlobalSection(NestedProjects) = preSolution 78 | {BDF69573-3578-4F32-AF57-2E8CF4A42FA8} = {1BFF9E60-8285-4FC6-8131-E61A5D9719FB} 79 | {4A2C892E-B840-4FDA-A0A7-14282D78BD7D} = {49BC71AC-23B9-4570-B8AB-B3DA4DC986D8} 80 | {4E3E85F5-3C7D-44CD-A0B6-5E1B02CDE8C4} = {49BC71AC-23B9-4570-B8AB-B3DA4DC986D8} 81 | EndGlobalSection 82 | EndGlobal 83 | -------------------------------------------------------------------------------- /Lib/Connector/Connector.cpp: -------------------------------------------------------------------------------- 1 | // Connector.cpp : Defines the exported functions for the DLL application. 2 | // 3 | 4 | #include "stdafx.h" 5 | #include "Connector.h" 6 | 7 | 8 | using namespace std; 9 | using namespace concurrency; 10 | using namespace concurrency::streams; 11 | using namespace utility; // Common utilities like string conversions 12 | using namespace web; // Common features like URIs. 13 | using namespace web::http; // Common HTTP functionality 14 | using namespace web::http::client; // HTTP client features 15 | using namespace concurrency::streams; // Asynchronous streams 16 | using namespace web::http::experimental::listener; // HTTP server 17 | using namespace web::experimental::web_sockets::client; // WebSockets client 18 | using namespace web::json; // JSON library 19 | using namespace app; 20 | 21 | Connector::Connector() 22 | { 23 | wcout << "constructor called" << endl; 24 | } 25 | 26 | Connector::~Connector() 27 | { 28 | wcout << "destructor called" << endl; 29 | } 30 | 31 | //Get a JSON response from web server 32 | void Connector::GetJson(const wstring& webServerUrl, 33 | const function& on_completed) const 34 | { 35 | _trace(L"%S %S", L"Connecting web server ", webServerUrl); 36 | uri _uri(webServerUrl); 37 | http_client client(_uri); 38 | 39 | client.request(methods::GET).then([=](http_response response) -> pplx::task 40 | { 41 | if(response.status_code() == status_codes::OK) 42 | { 43 | wcout << "got response" << endl; 44 | return response.extract_json(); 45 | } 46 | // Handle error cases, for now return empty json value... 47 | return pplx::task_from_result(json::value()); 48 | }).then([=](pplx::task previousTask) 49 | { 50 | wcout << "extracting json" << endl; 51 | const json::value& val = previousTask.get(); 52 | const wstring out = val.serialize(); 53 | if(on_completed != nullptr) 54 | { 55 | on_completed(out.c_str()); 56 | } 57 | else 58 | { 59 | wcout << "no callback to return JSON" << endl; 60 | } 61 | }); 62 | } 63 | //Get JSON response from web server 64 | void Connector::GetJson(const wstring& webServerUrl, const vector
& headers, 65 | const function& on_completed) const 66 | { 67 | _trace(L"%S %S", L"Connecting web server ", webServerUrl); 68 | uri _uri(webServerUrl); 69 | http_client client(_uri); 70 | http_request request(methods::GET); 71 | //copy headers 72 | for(Header h : headers) 73 | { 74 | wcout << "Header Key: " << h.Key << ", Value: " << h.Value << endl; 75 | request.headers().add(h.Key, h.Value); 76 | } 77 | 78 | //execute request 79 | client.request(request).then([=](http_response response) -> pplx::task 80 | { 81 | if(response.status_code() == status_codes::OK) 82 | { 83 | return response.extract_json(); 84 | } 85 | // Handle error cases, for now return empty json value... 86 | return pplx::task_from_result(json::value()); 87 | }).then([=](pplx::task previousTask) 88 | { 89 | const json::value& val = previousTask.get(); 90 | const wstring out = val.serialize(); 91 | if(on_completed != nullptr) 92 | { 93 | on_completed(out.c_str()); 94 | } 95 | else 96 | { 97 | wcout << "no callback to return JSON" << endl; 98 | } 99 | }); 100 | } 101 | 102 | extern "C" 103 | { 104 | 105 | void CONNECTOR_API __stdcall GetJson(const wchar_t* webServerUrl, on_completed callback) 106 | { 107 | Connector connector; 108 | const wstring _url(webServerUrl); 109 | auto _fun = function(callback); 110 | connector.GetJson(_url, _fun); 111 | } 112 | 113 | void CONNECTOR_API __stdcall GetJsonWithHeaders(const wchar_t* webServerUrl, const Header headers[], on_completed callback) 114 | { 115 | Connector connector; 116 | const wstring _url(webServerUrl); 117 | auto _fun = function(callback); 118 | const vector
_headers(headers, headers + sizeof headers / sizeof headers[0]); 119 | connector.GetJson(_url, _headers, _fun); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /Lib/Connector/Connector.h: -------------------------------------------------------------------------------- 1 | // The following ifdef block is the standard way of creating macros which make exporting 2 | // from a DLL simpler. All files within this DLL are compiled with the CONNECTOR_EXPORTS 3 | // symbol defined on the command line. This symbol should not be defined on any project 4 | // that uses this DLL. This way any other project whose source files include this file see 5 | // CONNECTOR_API functions as being imported from a DLL, whereas this DLL sees symbols 6 | // defined with this macro as being exported. 7 | #ifdef CONNECTOR_EXPORTS 8 | #define CONNECTOR_API __declspec(dllexport) 9 | #else 10 | #define CONNECTOR_API __declspec(dllimport) 11 | #endif 12 | 13 | //a simple Tracer 14 | #ifdef ENABLE_TRACE 15 | bool _trace(TCHAR *format, ...) 16 | { 17 | TCHAR buffer[2048]; 18 | 19 | va_list argptr; 20 | va_start(argptr, format); 21 | wvsprintf(buffer, format, argptr); 22 | va_end(argptr); 23 | 24 | OutputDebugString(buffer); 25 | 26 | return true; 27 | } 28 | #endif 29 | 30 | namespace app 31 | { 32 | //we use a C-style typedef to make the mapping of .NET delegates 33 | //easier (possible at all?) 34 | typedef void(__stdcall * on_completed)(const wchar_t*); 35 | 36 | //HTTP Header struct 37 | //here we use wchar_t* instead of wstring for easier marshalling of 38 | //.NET strings 39 | struct CONNECTOR_API Header 40 | { 41 | const wchar_t* Key; 42 | const wchar_t* Value; 43 | }; 44 | 45 | //implementation 46 | class CONNECTOR_API Connector 47 | { 48 | public: 49 | //Ctor 50 | Connector(void); 51 | //Get a JSON response from a web server. 52 | //The caller has to provide a function callback which will be 53 | //utilized to return server responses 54 | void GetJson(const std::wstring& webServerUrl, 55 | const std::function& on_completed) const; 56 | //Get a JSON response from a web werver. 57 | //This function accepts a vector of Headers 58 | //Also, the caller must provide a proper callback for reading the 59 | //server results 60 | void GetJson(const std::wstring& webServerUrl, 61 | const std::vector
& headers, 62 | const std::function& on_completed) const; 63 | //Dtor 64 | virtual ~Connector(); 65 | }; 66 | 67 | } 68 | 69 | extern "C" 70 | { 71 | //Get a JSON response from a web server 72 | void CONNECTOR_API __stdcall GetJson(const wchar_t* webServerUrl, app::on_completed callback); 73 | //Get a JSON response from a web server 74 | void CONNECTOR_API __stdcall GetJsonWithHeaders(const wchar_t* webServerUrl, 75 | const app::Header headers[], 76 | app::on_completed callback); 77 | 78 | } 79 | -------------------------------------------------------------------------------- /Lib/Connector/Connector.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Debug 7 | Win32 8 | 9 | 10 | Debug 11 | x64 12 | 13 | 14 | Release 15 | Win32 16 | 17 | 18 | Release 19 | x64 20 | 21 | 22 | 23 | {BDF69573-3578-4F32-AF57-2E8CF4A42FA8} 24 | Win32Proj 25 | Connector 26 | 27 | 28 | 29 | DynamicLibrary 30 | true 31 | v120 32 | Unicode 33 | 34 | 35 | DynamicLibrary 36 | true 37 | v120 38 | Unicode 39 | 40 | 41 | DynamicLibrary 42 | false 43 | v120 44 | true 45 | Unicode 46 | 47 | 48 | DynamicLibrary 49 | false 50 | v120 51 | true 52 | Unicode 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 550affdd 71 | 72 | 73 | true 74 | .\Debug 75 | 76 | 77 | true 78 | 79 | 80 | false 81 | .\Release 82 | 83 | 84 | false 85 | 86 | 87 | 88 | Use 89 | Level3 90 | Disabled 91 | WIN32;_DEBUG;_WINDOWS;_USRDLL;CONNECTOR_EXPORTS;%(PreprocessorDefinitions) 92 | true 93 | -Zm126 %(AdditionalOptions) 94 | 95 | 96 | Windows 97 | true 98 | Exports.def 99 | 100 | 101 | 102 | 103 | Use 104 | Level3 105 | Disabled 106 | WIN32;_DEBUG;_WINDOWS;_USRDLL;CONNECTOR_EXPORTS;%(PreprocessorDefinitions) 107 | true 108 | -Zm126 %(AdditionalOptions) 109 | 110 | 111 | Windows 112 | true 113 | Exports.def 114 | 115 | 116 | 117 | 118 | Level3 119 | Use 120 | MaxSpeed 121 | true 122 | true 123 | WIN32;NDEBUG;_WINDOWS;_USRDLL;CONNECTOR_EXPORTS;%(PreprocessorDefinitions) 124 | true 125 | 126 | 127 | Windows 128 | true 129 | true 130 | true 131 | Exports.def 132 | 133 | 134 | 135 | 136 | Level3 137 | Use 138 | MaxSpeed 139 | true 140 | true 141 | WIN32;NDEBUG;_WINDOWS;_USRDLL;CONNECTOR_EXPORTS;%(PreprocessorDefinitions) 142 | true 143 | 144 | 145 | Windows 146 | true 147 | true 148 | true 149 | Exports.def 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | false 164 | false 165 | 166 | 167 | 168 | 169 | false 170 | false 171 | 172 | 173 | 174 | 175 | 176 | 177 | Create 178 | Create 179 | Create 180 | Create 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 194 | 195 | 196 | 197 | 198 | -------------------------------------------------------------------------------- /Lib/Connector/Exports.def: -------------------------------------------------------------------------------- 1 | LIBRARY Connector 2 | EXPORTS 3 | GetJson @3 4 | GetJsonWithHeaders @4 5 | -------------------------------------------------------------------------------- /Lib/Connector/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | DYNAMIC LINK LIBRARY : Connector Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this Connector DLL for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your Connector application. 9 | 10 | 11 | Connector.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | Connector.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | Connector.cpp 25 | This is the main DLL source file. 26 | 27 | ///////////////////////////////////////////////////////////////////////////// 28 | Other standard files: 29 | 30 | StdAfx.h, StdAfx.cpp 31 | These files are used to build a precompiled header (PCH) file 32 | named Connector.pch and a precompiled types file named StdAfx.obj. 33 | 34 | ///////////////////////////////////////////////////////////////////////////// 35 | Other notes: 36 | 37 | AppWizard uses "TODO:" comments to indicate parts of the source code you 38 | should add to or customize. 39 | 40 | ///////////////////////////////////////////////////////////////////////////// 41 | -------------------------------------------------------------------------------- /Lib/Connector/dllmain.cpp: -------------------------------------------------------------------------------- 1 | // dllmain.cpp : Defines the entry point for the DLL application. 2 | #include "stdafx.h" 3 | 4 | BOOL APIENTRY DllMain( HMODULE hModule, 5 | DWORD ul_reason_for_call, 6 | LPVOID lpReserved 7 | ) 8 | { 9 | switch (ul_reason_for_call) 10 | { 11 | case DLL_PROCESS_ATTACH: 12 | case DLL_THREAD_ATTACH: 13 | case DLL_THREAD_DETACH: 14 | case DLL_PROCESS_DETACH: 15 | break; 16 | } 17 | return TRUE; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /Lib/Connector/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Lib/Connector/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // Connector.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /Lib/Connector/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | //#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 11 | // Windows Header Files: 12 | //#include 13 | 14 | #ifndef _MSC_VER 15 | #define NOEXCEPT noexcept 16 | #else 17 | #define NOEXCEPT _NOEXCEPT 18 | #endif 19 | 20 | #define ENABLE_TRACE 21 | 22 | // TODO: reference additional headers your program requires here 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include // HTTP server 31 | #include // JSON library 32 | #include // URI library 33 | #include // WebSocket client 34 | #include // Async streams backed by STL containers 35 | #include // Bridges for integrating Async streams with STL and WinRT streams 36 | #include // Async streams backed by raw pointer to memory 37 | #include // Async streams for producer consumer scenarios -------------------------------------------------------------------------------- /Lib/Connector/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## HTTP-Clients based on C++ REST SDK & C# ## 2 | This demo consists of three small VS projects: 3 | 4 | a) **C++ DLL with exported functions** 5 | 6 | b) **C++ Console App** using headers from DLL 7 | 8 | c) **C# Console App** using DllImport 9 | 10 | The DLL Exports are as follows: 11 | 12 | 13 | 14 | **C++ Client App** 15 | 16 | The C++ App uses the *Connector.h* header from DLL to create a *unique_ptr* 17 | of the Connector class. 18 | 19 | Connector utilizes internally the C++ REST SDK (Casablanca) to call a 20 | publicly available JSON Echo service. 21 | 22 | 23 | 24 | To make this example a little bit more realistic the method **GetJson** 25 | expects a function object. This object (a function pointer) is used to 26 | display the JSON response. There's also a possibility to send additional 27 | headers. 28 | 29 | Inside the **GetJson** method the server communication is handled asynchronously 30 | via objects & functions from the pplx namespace. 31 | 32 | **C# Client App** 33 | 34 | The .NET App imposes several restrictions to exported functions. 35 | Instead of C++ function templates I had to use old-style C function 36 | pointers. This is because .NET can only marshal Delegates to function pointers. 37 | The same happened to the C++ string class. It was replaced by 38 | raw *wchar_t* pointers. Ugly, but playing with .NET *DllImport* is always rather 39 | unpleasant. 40 | 41 | This is how the whole DllImport soup looks like: 42 | 43 | 44 | 45 | **First**, we declare a delegate and decorate it as an "unmanaged" (that is, non-NET callable) function pointer. Also, we set the 46 | calling convention to *StdCall*. This means that the callee (the DLL function) will be responsible to clean the stack and not the caller (the Client). More info 47 | on argument passing and calling conventions here. 48 | 49 | **Second**, we grab the DLL which hopefully exports the desired function. In this case the *Connector.dll* should be located where the executing assembly is. In other cases we'd adjust the first argument after *[DllImport]* Attribute. Also, the same calling convention is applied. 50 | Now, it's important to know that functions from non-NET DLLs are *statically imported externals* and very often demand special treatment of passed arguments. 51 | In this case we have to marshal a pure .NET entity, the Delegate to a raw function pointer To achieve this we use attribute *[MarshalAs]* and 52 | decorate the *OnCompletedDelegate* as *unmanaged function pointer*. 53 | 54 | **Finally**, the C++ DLL will be able to "call back" our delegate as soon as the JSON Echo Server delivers a response. 55 | 56 | *Example, C++ client calling service & passing additional headers* 57 | 58 | 59 | 60 | *Example, C# client calling service* 61 | 62 | 63 | 64 | **IMPORTANT** 65 | 66 | The clients need these two libraries to be located in their root folders: 67 | 68 | *Connector.dll* 69 | 70 | *cpprest120d_2_4.dll* (this is the library from C++ REST SDK and can be installed via Nuget) 71 | 72 | **LICENSE** 73 | 74 | MIT 75 | 76 | 77 | --------------------------------------------------------------------------------