├── 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 |
--------------------------------------------------------------------------------