KEMBAR78
Metro Style Apps from C++ Developers' View | PPTX
從 C++ 開發人員角度看
 Metro Style App 開發
     上官林傑 (ericsk)
     Technical Evangelist
          Microsoft
大綱
•   C++/CX 概論
•   開發 Metro Style App
•   Win32 API 與 COM
•   使用 AMP 透過 GPU 進行平行運算
用 C++ 的理由 (?)
• 只會寫 C/C++ (?)
• 移植 C/C++-based library
  – Using SQLite in a Metro Style App
• 為了更好的效能
Windows 8 開發平台
Windows 8 開發平台細節
C++/CX
Metro Style App 用的 C++
• C++/CX (Component Extensions)
• 用於 Metro Style App (以及 WinRT Component) 的開發
• 與 C++11 標準語法相容
  – 可以使用 STL
  – 在 desktop app 開發中也可以使用 C++11 的語法
• 加入 C++/CLI 的語法
  – Reference count
          命名空間 (namespace)
  – 提供基礎資料結構 <collection.h>
  – 相容 WinRT
Metro Style App 程式碼片段
                                                             C++/CX
// 建立 C++/CX 字串
auto message = ref new Platform::String(L"Hello, world");
// 建立訊息對話盒
auto dialog = ref new Windows::UI::Popups::MessageDialog(message);
// 顯示對話盒
dialog->ShowAsync();
                                                   WinRT Component
C++11 語法範例
IAsyncOperation<IMap<String^, Object^>^>^
Class1::DoSomethingAsync(String^ uri, IMap<String^, Object^>^
parameters)
{
    auto params = make_shared<MyParams>();
    params->uri = uri->Data();              Type interface



for_each(begin(parameters), end(parameters), [params](IKeyValuePair<Stri
ng^, Object^>^ value) {
        params->parameters.push_back(tuple<wstring, wstring>(value->Key-
>Data(), value->Value->ToString()->Data()));
    });
                                               lambda function
    ....
}
編譯 C++/CX
• 產生 native code
  – C++/CLI 產生執行於 CLI 上的 IL code,C++/CX 則是直接產生機
    器碼
     • Power/Performance-efficiency
  – 開發 metro style app 必須針對 x86, x64 以及 ARM 三種平台做
    app package
開發 METRO STYLE APPS
(WINRT)
XAML
• 宣告式 UI 框架
  <Button x:Name="MyButton" Width="80" Height="50" Content="Click" />
  相當於 C++ 程式碼
  Button^ b = ref new Button();
  b->Name = L"MyButton";
  b->Width = 80;
  b->Height = 50;
  b->Content = L"Click";

• 可以用 Blend 或 VS Visual Designer 編輯
• 與程式碼緊密結合
DEMO: METRO STYLE APP
WinRT Component 開發

• 加速或加密 Metro Style App 中的某部份
  – 不得已需要使用某些 Win32 API 或是 COM
• 透過「語言映射」(Language Projection) 技術,讓以
  C++/C#/VB.net 所開發出來的 WinRT component 得以讓
  各種語言寫的 metro style app 所使用
  – 針對不同平台都要 build 一份 .dll/.winmd 給 metro style app 用
使用 Windows Runtime 範本
           #pragma once

           namespace WindowsRuntimeComponent1
           {
               public ref class Class1 sealed
               {
               public:
                   Class1();

                   Platform::String^ SayHello()
                   {
                       auto hello = ref new
           Platform::String(L"Hello!");
                       return hello;
                   }
               };
           }


                     實作 sealed 類別
Hybrid Metro Style App
                   • 在 Metro Style App 的專案中將這兩個檔
                     案「加入參考」 (Add References)
                   • 接著就像使用 app 開發所使用的語言一樣
                     呼叫 WinRT component API


                   // 就像在建立一個 JavaScript 物件
                   var compo = new WindowsRuntimeComponent1.Class1();
                   // 為 JavaScript 而將函式名轉成 camel case style
                   var helloStr = compo.sayHello();



取出 .dll 及 .winmd
DEMO: WINRT COMPONENT
WIN32 API 以及 COM
使用 Win32 API 以及 COM
• 追求極致的效能
• 移植過去的程式
• 只有部份的 Win32 API 及 COM 可以在 Metro Style App
  中使用
  – WACK 可以協助確認是否可以用
  – 參考可以使用的列表:
    http://msdn.microsoft.com/en-us/library/windows/apps/br205753.aspx
  – 或是看標頭檔是否有標示:
    #pragma region Application Family
    #pragma region Desktop Family
使用 COM
• 透過 Windows Runtime C++ Template Library (WRL)來
  呼叫
  ComPtr<interface_name> ptr;
  HRESULT hr = CoCreateInstanceEx(CLSID_XXX...);
  if (FAILED(hr))
  {
      // process error
  }


• 自己實作的 COM 物件必須實作 IInspectable 介面,並且
  由 Microsoft::WRL::Details::RuntimeClass 實作物件
• 除非有必要使用的 COM,否則不建議這麼做
範例: 使用 MSXML
// 實作 IXMLHttpRequest2Callback 介面
class HttpRequestCallback
    : public
RuntimeClass<RuntimeClassFlags<ClassicCom>, IXMLHTTPRequest2Callback, Ft
mBase>
{
    ...
    // 實作收到回應的回呼函式
    IFACEMETHODIMP
OnResponseReceived(IXMLHTTPRequest2*, ISequentialStream*
pResponseStream)
    {
        ...
    }
    ...
}
範例: 使用 MSXML (續)
// 使用 COM
ComPtr<IXMLHTTPRequest2> xhr;
// 建立實體
HRESULT hr =
CoCreateInstance(CLSID_XmlHttpRequest, nullptr, CLSCTX_INPROC, IID_PPV_A
RGS(&xhr));
if (FAILED(hr))
{
    // 處理錯誤
}
// 建立 callback 實體
auto callback = Make<HttpRequestCallback>(xhr.Get(), cancellationToken);
...
// 建立連線及設定 callback
hr = xhr-
>Open(method.c_str(), uri.c_str(), callback.Get(), nullptr, nullptr, nul
lptr, nullptr);
...
// 送出 request
hr = xhr->Send(nullptr, 0);
DEMO: 使用 MSXML6 COM
使用 AMP 做平行運算
AMP
• Accelerated Massive Parallelism
       – 相較於 PPL 是利用 CPU 做平行運算,AMP 用 GPU 平行運算
       – 不一定只有 Metro Style App 可以用
• C++-style Library
       – 相較於其它的 GPU 加速程式碼
       – 加速20倍以上
• 函式庫
       – VS2012 導入,也包含在可散佈套件中
       – 規格是公開的




Ref:
使用 AMP
• #include <amp.h>
             concurrency

  – array array_view
  – extent index
  – accelerator accelerator_view
                    parallel_for_each
                           restrict
  – Asks compiler to check your code is ok for GPU (DirectX)
Array 相加範例
void AddArrays(int n, int *        #include <amp.h>
pA, int * pB, int * pSum)          using namespace concurrency;
{                                  void AddArrays(int n,   int * pA, int
    for (int i=0; i<n; i++)        * pB, int * pSum)
    {                              {
                                       array_view<int,1>   a(n, pA);
        pSum[i] = pA[i] + pB[i];       array_view<int,1>   b(n, pB);
    }                                  array_view<int,1>   sum(n, pSum);
}
                                       parallel_for_each(
                                           sum.extent,
                                           [=](index<1> i)
                                   restrict(amp)
                                           {
                                               sum[i] = a[i] + b[i];
                                           }
                                        );
                                   }
分析 AMP 程式碼
                                                                 array_view: 將原本的陣列轉成
                                                                 可以 AMP 處理的資料結構

                       void AddArrays(int n,   int * pA, int *
                       pB, int * pSum)
parallel_for_each: 將   {
lambda 放在所有的               array_view<int,1>   a(n, pA);
thread 上執行                 array_view<int,1>   b(n, pB);
                           array_view<int,1>   sum(n, pSum);
                                                               restrict(amp): 問 compiler 是否可以
                           parallel_for_each(              使用 AMP 函式庫
                               sum.extent,
                               [=](index<1> i) restrict(amp)
extent: thread 間共用             {
的物件
                                       sum[i] = a[i] + b[i];
                               }
                            );
                       }
                                                      array_view 變數可以移到 GPU 來
index: 用來辨別是哪一個 thread 執行
                                                      平行處理
使用 AMP 的限制
• No                        • No
  – recursion                 –    goto or labeled statements
                              –    throw, try, catch
  – 'volatile'
                              –    globals or statics
  – virtual functions         –    dynamic_cast or typeid
  – pointers to functions     –    asm declarations
  – pointers to member        –    varargs
    functions                 –    unsupported types
                                    • e.g. char, short, long
  – pointers in structs               double
  – pointers to pointers
  – bitfields
DEMO: MATRIX
MULTIPLICATION
用 C++ 的理由
• 只會寫 C/C++ (?)
• 移植 C/C++-based library
  – Using SQLite in a Metro Style App
• 為了更好的效能
  – 針對平台的加速
  – 使用 AMP 利用 GPU 做平行運算
  – 操作 COM
     • 更極致的效能調校
     • 使用 DirectX 11 開發遊戲
參考資源
•   Visual C++ Language Reference (C++/CX)
    http://msdn.microsoft.com/en-us/library/windows/apps/hh699871.aspx

•   Developing Windows 8 Metro style apps with C++
    http://channel9.msdn.com/Events/Windows-Camp/Developing-Windows-8-Metro-style-apps-in-Cpp

•   Win32 and COM API
    http://msdn.microsoft.com/en-us/library/windows/apps/br205757

•   AMP MSDN Library
    http://msdn.microsoft.com/en-us/library/hh265137(v=vs.110)
    Native Concurrency Blog
    http://blogs.msdn.com/b/nativeconcurrency/

•   Developing games
    http://msdn.microsoft.com/en-us/library/windows/apps/hh452744.aspx

•   Visual C++ Team Blog
    http://blogs.msdn.com/b/vcblog/

Metro Style Apps from C++ Developers' View

  • 2.
    從 C++ 開發人員角度看 Metro Style App 開發 上官林傑 (ericsk) Technical Evangelist Microsoft
  • 3.
    大綱 • C++/CX 概論 • 開發 Metro Style App • Win32 API 與 COM • 使用 AMP 透過 GPU 進行平行運算
  • 4.
    用 C++ 的理由(?) • 只會寫 C/C++ (?) • 移植 C/C++-based library – Using SQLite in a Metro Style App • 為了更好的效能
  • 5.
  • 6.
  • 7.
  • 8.
    Metro Style App用的 C++ • C++/CX (Component Extensions) • 用於 Metro Style App (以及 WinRT Component) 的開發 • 與 C++11 標準語法相容 – 可以使用 STL – 在 desktop app 開發中也可以使用 C++11 的語法 • 加入 C++/CLI 的語法 – Reference count 命名空間 (namespace) – 提供基礎資料結構 <collection.h> – 相容 WinRT
  • 9.
    Metro Style App程式碼片段 C++/CX // 建立 C++/CX 字串 auto message = ref new Platform::String(L"Hello, world"); // 建立訊息對話盒 auto dialog = ref new Windows::UI::Popups::MessageDialog(message); // 顯示對話盒 dialog->ShowAsync(); WinRT Component
  • 10.
    C++11 語法範例 IAsyncOperation<IMap<String^, Object^>^>^ Class1::DoSomethingAsync(String^uri, IMap<String^, Object^>^ parameters) { auto params = make_shared<MyParams>(); params->uri = uri->Data(); Type interface for_each(begin(parameters), end(parameters), [params](IKeyValuePair<Stri ng^, Object^>^ value) { params->parameters.push_back(tuple<wstring, wstring>(value->Key- >Data(), value->Value->ToString()->Data())); }); lambda function .... }
  • 11.
    編譯 C++/CX • 產生native code – C++/CLI 產生執行於 CLI 上的 IL code,C++/CX 則是直接產生機 器碼 • Power/Performance-efficiency – 開發 metro style app 必須針對 x86, x64 以及 ARM 三種平台做 app package
  • 12.
    開發 METRO STYLEAPPS (WINRT)
  • 13.
    XAML • 宣告式 UI框架 <Button x:Name="MyButton" Width="80" Height="50" Content="Click" /> 相當於 C++ 程式碼 Button^ b = ref new Button(); b->Name = L"MyButton"; b->Width = 80; b->Height = 50; b->Content = L"Click"; • 可以用 Blend 或 VS Visual Designer 編輯 • 與程式碼緊密結合
  • 14.
  • 15.
    WinRT Component 開發 •加速或加密 Metro Style App 中的某部份 – 不得已需要使用某些 Win32 API 或是 COM • 透過「語言映射」(Language Projection) 技術,讓以 C++/C#/VB.net 所開發出來的 WinRT component 得以讓 各種語言寫的 metro style app 所使用 – 針對不同平台都要 build 一份 .dll/.winmd 給 metro style app 用
  • 16.
    使用 Windows Runtime範本 #pragma once namespace WindowsRuntimeComponent1 { public ref class Class1 sealed { public: Class1(); Platform::String^ SayHello() { auto hello = ref new Platform::String(L"Hello!"); return hello; } }; } 實作 sealed 類別
  • 17.
    Hybrid Metro StyleApp • 在 Metro Style App 的專案中將這兩個檔 案「加入參考」 (Add References) • 接著就像使用 app 開發所使用的語言一樣 呼叫 WinRT component API // 就像在建立一個 JavaScript 物件 var compo = new WindowsRuntimeComponent1.Class1(); // 為 JavaScript 而將函式名轉成 camel case style var helloStr = compo.sayHello(); 取出 .dll 及 .winmd
  • 18.
  • 19.
  • 20.
    使用 Win32 API以及 COM • 追求極致的效能 • 移植過去的程式 • 只有部份的 Win32 API 及 COM 可以在 Metro Style App 中使用 – WACK 可以協助確認是否可以用 – 參考可以使用的列表: http://msdn.microsoft.com/en-us/library/windows/apps/br205753.aspx – 或是看標頭檔是否有標示: #pragma region Application Family #pragma region Desktop Family
  • 21.
    使用 COM • 透過Windows Runtime C++ Template Library (WRL)來 呼叫 ComPtr<interface_name> ptr; HRESULT hr = CoCreateInstanceEx(CLSID_XXX...); if (FAILED(hr)) { // process error } • 自己實作的 COM 物件必須實作 IInspectable 介面,並且 由 Microsoft::WRL::Details::RuntimeClass 實作物件 • 除非有必要使用的 COM,否則不建議這麼做
  • 22.
    範例: 使用 MSXML //實作 IXMLHttpRequest2Callback 介面 class HttpRequestCallback : public RuntimeClass<RuntimeClassFlags<ClassicCom>, IXMLHTTPRequest2Callback, Ft mBase> { ... // 實作收到回應的回呼函式 IFACEMETHODIMP OnResponseReceived(IXMLHTTPRequest2*, ISequentialStream* pResponseStream) { ... } ... }
  • 23.
    範例: 使用 MSXML(續) // 使用 COM ComPtr<IXMLHTTPRequest2> xhr; // 建立實體 HRESULT hr = CoCreateInstance(CLSID_XmlHttpRequest, nullptr, CLSCTX_INPROC, IID_PPV_A RGS(&xhr)); if (FAILED(hr)) { // 處理錯誤 } // 建立 callback 實體 auto callback = Make<HttpRequestCallback>(xhr.Get(), cancellationToken); ... // 建立連線及設定 callback hr = xhr- >Open(method.c_str(), uri.c_str(), callback.Get(), nullptr, nullptr, nul lptr, nullptr); ... // 送出 request hr = xhr->Send(nullptr, 0);
  • 24.
  • 25.
  • 26.
    AMP • Accelerated MassiveParallelism – 相較於 PPL 是利用 CPU 做平行運算,AMP 用 GPU 平行運算 – 不一定只有 Metro Style App 可以用 • C++-style Library – 相較於其它的 GPU 加速程式碼 – 加速20倍以上 • 函式庫 – VS2012 導入,也包含在可散佈套件中 – 規格是公開的 Ref:
  • 27.
    使用 AMP • #include<amp.h> concurrency – array array_view – extent index – accelerator accelerator_view parallel_for_each restrict – Asks compiler to check your code is ok for GPU (DirectX)
  • 28.
    Array 相加範例 void AddArrays(intn, int * #include <amp.h> pA, int * pB, int * pSum) using namespace concurrency; { void AddArrays(int n, int * pA, int for (int i=0; i<n; i++) * pB, int * pSum) { { array_view<int,1> a(n, pA); pSum[i] = pA[i] + pB[i]; array_view<int,1> b(n, pB); } array_view<int,1> sum(n, pSum); } parallel_for_each( sum.extent, [=](index<1> i) restrict(amp) { sum[i] = a[i] + b[i]; } ); }
  • 29.
    分析 AMP 程式碼 array_view: 將原本的陣列轉成 可以 AMP 處理的資料結構 void AddArrays(int n, int * pA, int * pB, int * pSum) parallel_for_each: 將 { lambda 放在所有的 array_view<int,1> a(n, pA); thread 上執行 array_view<int,1> b(n, pB); array_view<int,1> sum(n, pSum); restrict(amp): 問 compiler 是否可以 parallel_for_each( 使用 AMP 函式庫 sum.extent, [=](index<1> i) restrict(amp) extent: thread 間共用 { 的物件 sum[i] = a[i] + b[i]; } ); } array_view 變數可以移到 GPU 來 index: 用來辨別是哪一個 thread 執行 平行處理
  • 30.
    使用 AMP 的限制 •No • No – recursion – goto or labeled statements – throw, try, catch – 'volatile' – globals or statics – virtual functions – dynamic_cast or typeid – pointers to functions – asm declarations – pointers to member – varargs functions – unsupported types • e.g. char, short, long – pointers in structs double – pointers to pointers – bitfields
  • 31.
  • 32.
    用 C++ 的理由 •只會寫 C/C++ (?) • 移植 C/C++-based library – Using SQLite in a Metro Style App • 為了更好的效能 – 針對平台的加速 – 使用 AMP 利用 GPU 做平行運算 – 操作 COM • 更極致的效能調校 • 使用 DirectX 11 開發遊戲
  • 33.
    參考資源 • Visual C++ Language Reference (C++/CX) http://msdn.microsoft.com/en-us/library/windows/apps/hh699871.aspx • Developing Windows 8 Metro style apps with C++ http://channel9.msdn.com/Events/Windows-Camp/Developing-Windows-8-Metro-style-apps-in-Cpp • Win32 and COM API http://msdn.microsoft.com/en-us/library/windows/apps/br205757 • AMP MSDN Library http://msdn.microsoft.com/en-us/library/hh265137(v=vs.110) Native Concurrency Blog http://blogs.msdn.com/b/nativeconcurrency/ • Developing games http://msdn.microsoft.com/en-us/library/windows/apps/hh452744.aspx • Visual C++ Team Blog http://blogs.msdn.com/b/vcblog/