SlideShare a Scribd company logo
C++/CLI 概觀 王建興 qing@cs.nthu.edu.tw (Email/MSN) 2007/1/25
About Qing Education Ph.D. Candidate, Department of Computer Science, National Tsing-Hua University, Taiwan Research interests: distribute network management, mobile agent, VoIP, and p2p networking Software Development Skills Programming languages: 80x86 assembly, C/C++, Java, C# J2EE development and Web programming: EJB, JSP/Servlet Network programming: TCP/IP, socket programming Object Oriented Design/Programming Design Patterns and Software Architecture  Distributed Network Management System Peer-to-Peer Networking Book Translation Thinking in Java 2nd Edition, in Traditional Chinese Essential C++, in Traditional Chinese
Agenda 何謂 C++/CLI C++/CLI 中的型別宣告 Handle vs. Pointer Deterministic Destruction  of C++/CLIS C++/CLI 中的陣列 C++/CLI 對 Property 的支援 C++/CLI 的四種編譯模式 Templates 及 Generics C++/CLI 的標準化
在 C++/CLI 出現前, .NET 上的 C++ 程式員恐怕只有一個字可以形容 悶
.NET 上的 C++ 程式員為什麼悶? (1/2) 僅管有了 Managed Extension for C++ ,但卻存在一些對程式員的困擾 不夠流暢優雅的語法 例如:雙底線的關鍵字們 對 CLI 的支援不夠支接 例如:缺乏 for-each 語法,不支援 property C++ 與 .NET 之間的整合不夠好 例如:無法在 CLI 型別上使用 template ,也無法在 C++ 型別上運用 CLI 的機制,例如垃圾回收 *http://www.codeproject.com/managedcpp/cppcliintro01.asp
.NET 上的 C++ 程式員為什麼悶? (2/2) 有兩種形式的指標: unmanaged  指標及 managed 指標,其用法及表示容易造成混淆 無法產生 verifiable 的程式碼
為什麼不學 C# 就好了? 多學一個程式語言 C++ 最佳化能力較強 C++ 具備 deterministic destruction (即使編譯為 MSIL ) C++ 程式員在 C++ 的特性支持下,生產力較高 STL template specialization
好消息是… .Net 上的 C++ 程式員不用再悶了
C++/CLI 所帶來的拯救 優雅流暢的語法 對 CLI 的直接支援 property ,泛型,垃圾回收等機制全都有了直接的支援 在 unmanaged classes 上這些機制也都適用 妥善的橋接 .NET 與 C++ 透過 C++/CLI 編譯出來的程式碼,是 fully verifiable *http://www.codeproject.com/managedcpp/cppcliintro01.asp
何謂 C++/CLI ? C++ 所支援的靜態物件模型,目標放在對執行檔速度及大小的最佳化上 CLI 則為一支援動態元件編程模型的多階架構 C++/CLI 中的” /” ,代表 C++ 與 CLI 之間的 binding 何謂 C++/CLI 近似說法 1 : C++/CLI 將 C++ 靜態的物件模型繫結 (bind) 至 CLI 的動態元件模型 近似說法 2 : C++/CLI 將 .NET 編程模型整合進到 C++ 中 * Stanley B. Lippman , http://msdn.microsoft.com/msdnmag/issues/06/00/PureC/default.aspx
C++/CLI 就是 C++ X CLI 確定性的記憶體管理 Template Native types STL 、 generic algorithms 指標 複製建構及指派 垃圾收集, finalizer 泛型 Reference 及 value types Interface Verifiability Security Properties, delegates, events 功能強力的 BCL C++ 的特點 CLI 的特點 C++/CLI 發揮 C++ 及 CLI 的相乘效果
C++/CLI 的目標就是 無接縫式的整合 Unmanaged 及 Managed Code
C++ 及 CLI 物件模型的比較 物件儲存空間類型多樣化 static, stack,  以及 heap 物件的生命期類型多樣化 static object 有著和程式相同的生命期 stack 上的 object ,則在和 scope({ … }) 的生命期相同 heap 上的 object ,則由程式員自行操控其生命期 物件建構及指派的深層拷貝模型 編譯時,原始碼中必須含括所有動用型別的資訊 物件儲存空間類型單純 Value type 儲存於 stack Reference type 儲存於 managed heap 上 物件的生命期具不確定性 Reference types 須倚靠垃圾收集器回收 物件的指派採淺層參考語義 編譯時,型別資訊由所使用型別的 metadata 提供 C++ 的靜態物件模型 CLI 的動態物件模型
C++/CLI 中的型別宣告 在 C++/CLI 中可宣告下述型別 CLR 的 enumeration type enum class E {…} CLR 的 interface type interface class I {…} CLR 的 value type value class V {…} CLR 的 reference type ref class R {…} C++ 原生類別(過去 C++ 程式員所用) class N {…} 所宣告的型別 宣告語法
C++ 與 CTS 型別的對應 N/A Boolean bool N/A Double long double N/A Double double N/A Single float UInt64 Int64 __int64 UInt32 Int32 long int UInt32 Int32 int, __int32 UInt16 Int16 short int Byte Sbyte char CTS Unsigned Type CTS Signed Type C++ Type
各型別的用途 原生型別 具備 native code 的語義及優點 即使被編譯成 MSIL 亦如此 Reference Type 可被垃圾收集器回收,提供簡便的記憶體管理模式 Value Type 輕量級的型別(例如像整數之類的型別) Interface Type 宣告 CLR 中的介面型別 Enumeration Type 宣告 CLR 中的列舉型別
例:在 C++/CLI 中宣告 Reference Type ref  class Qing { public: void sayHello(); }; void Qing::sayHello() { Console::WriteLine("Hello!"); } 多半宣告在 .h 檔裡 多半宣告在 .pp 檔裡
Handle vs. Pointer C++/CLI 中將 native C++ 型別及 CLI 型別區分開來 C++/CLI 中同樣具備指向 CLI 型別的 ” 指標”,但採用了不同的符號來表示,同時賦予一個不同的名稱,以資區別 這個名稱就是 Handle (相對於 Pointer ) 這個符號就是 ^ (相對於 * ) 建構 native C++ 型別及 CLI 型別的關鍵字也已有所區隔 new :產生 native C++ 型別 gcnew :產生 CLI 型別( gc 意指 garbage collected ,垃圾回收之意)
透過 Handle 建構並運用 CLI 型別 Qing  ^ qing =  gcnew  Qing(); qing->sayHello();
使用 Pointer 和 Handle 的差異 Pointer 用來在 native heap 中配置空間 語法: T* t = new T; 指標指向的位置是穩定的(不受 GC 影響),甚至可以被轉型為 int 倘若未自行釋放記憶體( delete ),則會產生 memory leak Handle 用來在 managed heap 中配置空間 語法: T^ t = gcnew T;  GC 會自動釋放位於 managed heap 中的物件所佔用的空間 但程式員仍可針對 managed heap 上的物件呼叫 delete
不同的兩種物件生成及運用模式 *Kate Gregory, “Moving C++ Applications to the Common Language Runtime”     Use Native Heap    Use Managed Heap   Use Stack ^ and % always * and & never Verifiability d elete delete Free gcnew new Allocate % & Reference ^ * Pointer / Handle Managed Native
於 Native/CLI 型別中混用 Pointer/Handle (1/2) 在 CLI 型別中使用 Handle 在 CLI 型別中使用 Pointer ref class R { private: String ^str; } ref class R { private: std::string* str;  }
於 Native/CLI 型別中混用 Pointer/Handle (2/2) 在 Native 型別中使用 Handle gcroot<T> 是用來包裝 System.Runtime.InteropServices.GCHandle 的一個 template class *http://www.codeproject.com/managedcpp/ijw_unmanaged.asp class N { private: gcroot<String^> str;; }
Tracking Reference Operator % & 之於 pointer ,相當於 % 之於 handle R1 ^pr1 = gcnew R1(); R1 %r1 =  * pr1; Console::WriteLine(r1 . ToString()); 不再是  -> 同樣使用 *
Tracking Reference 的效應 array<String^>^ arr = gcnew array<String^>(3); int i = 0; for each(String^% s in arr) s = gcnew String(i++.ToString()); for each(String^ s in arr) Console::WriteLine(s); 執行結果: 0 1 2 array<String^>^ arr = gcnew array<String^>(3); int i = 0; for each(String^ s in arr) s = gcnew String(i++.ToString()); for each(String^ s in arr) Console::WriteLine(s); 執行結果:
CLI 的 Non-Deterministic Finalization CLI 的垃圾回收機制,會在記憶體傾向不足時,將不再使用被物件佔用的記憶體空間回收再用 當物件佔用的記憶體空間確定被回收前的一刻,該物件的 Finalize() 會被呼叫,此即為 finalization (終始化)動作 Finalization 執行的時機及是否會被執行任誰都說不得準 所以被稱為 non-deterministic finalization
Disposal 對於記憶體資源而言,  non-deterministic finalization 不成問題 但對非記憶體資料(例如資料庫 、 檔案), 面對 non-deterministic finalization 的程式員得多費心才能使程式如預期的運作 對 .NET 而言,慣例上清理此類資料的動作,會定義於名為 Close() 或 Dispose() 的方法中 但這麼一來,程式員得自行呼叫 Close() 或 Dispose() 來進行清理動作
Deterministic Destruction C++/CLI 除了 CLI 上原先就有的 finalizer 之外,還提供了 destructor. ref class R1 { public: R1() {} ~R1() {} protected: !R1() {}  }; constructor destructor finalizer * 注意: C++/CLI 使用了 C# 中用來表示 Finalizer 的符號來表示 Destructor
Finalizer vs. Destructor C++/CLI 中的 Destructor 最終會被編譯成為 Dispose() ,如果用 C# 的相對應程式碼來看的話,會像是: GC::SuppressFinalize() 會要求系統不要呼叫物件的 finalizer() ,避免物件被清理兩次 public void Dispose()//IDisposable::Dispose { GC.SuppressFinalize(this); } *http://www.codeproject.com/managedcpp/cppclidtors.asp *http://msdn2.microsoft.com/en-us/library/system.gc.suppressfinalize.aspx
Why  SuppressFinalize?   public class FileStream : Stream { public override void Close() { // Clean up this object: flush data and close file  … // There is no reason to Finalize this object now GC.SuppressFinalize(this); } protected override void Finalize() { Close();  // Clean up this object: flush data and close file } // Rest of FileStream methods go here … } *http://www.codeproject.com/managedcpp/cppclidtors.asp 如果程式員自行呼叫了 Close() , 但 GC 又呼叫了 Finalize() 便會引發 Close() 被叫用兩次
自動進行的 Disposal { SqlConnection conn(connString); } constructor 會被呼叫 destructor 會被自動呼叫 {   SqlConnection ^pConn = gcnew SqlConnection(connString); } constructor 會被呼叫 之後就要等待 GC 動作了
C++/CLI 中的陣列 使用 Managed Heap 的 Managed Array ,其基礎型別皆為 System::Array 使用 C++/CLI 的陣列時,可以想像存在一個虛擬的 template http://www.codeproject.com/managedcpp/cppcliarrays.asp namespace stdcli::language { template<typename T, int rank = 1> ref class array : System::Array {}; }
陣列定義語法 一維陣列語法 多維度陣列語法 array<String ^> ^ strArray = gcnew array<String ^>(10); for(int i=0;i<strArray->Length;i++) { strArray[i] = &quot;&quot;+i; Console::WriteLine(strArray[i]); } array<String ^, 3> ^ strArray = gcnew array<String ^, 3>(4, 3, 2); 維度 每個維度的長度
陣列的初始化 array<String^>^ strarr = gcnew array<String^> {“String1&quot;, “String2&quot;}; array<String^>^ strarr2 = {“String1&quot;, “String2&quot;}; array<Object^,2> ^ objarr = {{“String1&quot;, 1}, {“String2&quot;, 2}};
參數陣列 C++/CLI 支援參數陣列,參數陣列必須是最後一個參數 用…來標示參數陣列 void testParamArray(String ^s,  ...  array<String ^>^ params) { Console::WriteLine(s+&quot;: &quot;); for(int i=0;i<params->Length;i++) Console::WriteLine(params[i]); } int main(array<System::String ^> ^args) { testParamArray(&quot;Hello&quot;, &quot;qing&quot;); testParamArray(&quot;Hello&quot;, &quot;qing&quot;, &quot;chrisma&quot;); }
Property 的語法 ref class UserAccount { public: property String^ ID { String^ get(){return id;} virtual void set(String^ value){id = value;} } private: String^ id; }; 就和 C# 的定義方式類似
Index Property 的語法 ref class OnlineUserList{ public: property UserAccount^  User[int]  { UserAccount^ get(int idx){return (UserAccount^) alUser[idx];} } OnlineUserList() { alUser = gcnew System::Collections::ArrayList(); } // …  private: System::Collections::ArrayList ^alUser; };
Refernece Type 允許單一繼承多重實作 ref class R abstract {};  public ref class R2 : R, IClone, IComparable, IDisposable, IEnumerable { };  所有 reference type 都繼承自 System::Object 最多繼承一個類別,但可以實作多個介面
Exception Handling try { throw gcnew Exception(&quot;qing&quot;); } catch(System::Exception^ e) { Console::WriteLine(e->StackTrace); }
CLR 編譯模式:共有四種可供選擇 Mix( /clr) 包含 managed/unmanaged code Pure( /clr:pure ) 僅包含 managed code 但仍可使用 #include 並呼叫原生 API Verifiable( clr:safe) 僅包含 verifiable code Managed Extensions for C++( clr:oldSyntax ) 用來編譯舊式的程式碼
在 VS 2005 中選擇編譯模式
編譯模式之間的關連性 Native CLR Code Data Machine Code CLR Data / Types Native Data / Types MSIL Code Mixed C++ /clr Native C++ Verifiable C++ /clr:safe Pure C++ /clr:pure
CLR 編譯模式帶來的應用 在 C++ 應用程式中直接使用 BCL 或以 .NET 寫成的 library 大幅提高生產力 將 native code 的功能,以 .NET 物件模型的方式對外提供 便於其他 .NET 應用程式使用( ASP.NET )
決定 Managed/Unmanaged 的交界處 C++ managed C++ CRT, STL, etc One call to foo() Hundreds of calls C# or C++ managed C++ CRT, STL, etc One call to foo() Hundreds of calls C# C++ CRT, STL, etc Hundreds of calls C++ One call to foo() One call * Kate Gregory, “ Moving C++ Applications to the Common Language Runtime”
C++/CLI 支援 Template template<typename T1, typename T2> class NativeData { public: NativeData(T1 t1) { m_t1 = t1; } void DoStuff(T2 t2) { //... } private: T1 m_t1; }; *http://www.codeproject.com/managedcpp/cppcligenerics.asp
Tempalte 採用 Lazy Constraint (1/2) template<typename T> class Native { public: void Start(int x) { T* t = new T(); t->Bark(x); t->WagTail(); delete t; } }; 如何確定 t 有 Bark() 及 WagTail() 兩 methods 呢? *http://www.codeproject.com/managedcpp/cppcligenerics.asp
Tempalte 採用 Lazy Constraint (2/2) Native<NativeDog> d1; d1.Start(100); Native<NativePig> d2; d2.Start(100); 引發編譯器錯誤: error C2039: 'Bark' : is not a member of 'NativePig' *http://www.codeproject.com/managedcpp/cppcligenerics.asp
C++/CLI 支援 Generics generic<typename T1, typename T2> ref class GenericData { public: GenericData(T1 t1) { m_t1 = t1; } void DoStuff(T2 t2) { //... } private: T1 m_t1; }; *http://www.codeproject.com/managedcpp/cppcligenerics.asp
Generics 採用 Subtype Constraints (1/3) generic<typename T>  where T:IDog  ref class GenRef  { public: void Start(int x) { T t = Activator::CreateInstance<T>(); t->Bark(x); t->WagTail(); delete safe_cast<Object^>(t);  } }; 透過限制 T 必須實作的介面來進行約束 *http://www.codeproject.com/managedcpp/cppcligenerics.asp
Generics 採用 Subtype Constraints (2/3) ref class ClrDog : IDog { public: virtual void Bark(int Loudness) { Console::WriteLine(&quot;ClrDog::Bark {0}&quot;,Loudness); } virtual void WagTail() { Console::WriteLine(&quot;ClrDog::WagTail&quot;); } }; *http://www.codeproject.com/managedcpp/cppcligenerics.asp
Generics 採用 Subtype Constraints (3/3) GenRef<ClrDog^> g1; g1.Start(100); *http://www.codeproject.com/managedcpp/cppcligenerics.asp
使用 Reference Types 於 Template template<typename T> class CLR { public: void Start(int x) { T^ t = gcnew T(); t->Bark(x); t->WagTail(); delete t; } }; CLR<ClrDog> g2; g2.Start(100)
將 Template 宣告為 Reference Type template<typename T>  ref  class CLR2 { public: void Start(int x) { T^ t = gcnew T(); t->Bark(x); t->WagTail(); delete t; } }; CLR 2 <ClrDog> g 3 ; g 3 .Start(100) Console::WriteLine(g3.GetType()->Name); 執行結果: ClrDog::Bark 100 ClrDog::WagTail CLR2<ClrDog>
Generics Functions generic<typename T> where T:IDog void DoAll(T t) { t->Bark(0); t->WagTail(); } *http://www.codeproject.com/managedcpp/cppcligenerics.asp
Template vs. Generics Templates are instantiated at  compile-time  with the source code.  The type checking of a template are performed at the point where the template is   defined  and  instantiated . Tempaltes  allow  specialization. Templates  allow  non-type parameters.  Templates use &quot; lazy structural constraints &quot;.  Generics are instantiated at   run-time  by the CLR.  The type checking of  a generic is peformend at the point where the generic is  defined . Generics are  cross-language .  Generics  do not allow  specialization. Generics  do not allow  non-type parameters.  Generics use  subtype constraints .  *http://blogs.msdn.com/branbray/archive/2003/11/19/51023.aspx
Verifiable C++ 以 /clr:safe 編譯,將會試著產生 verifiable assembly 若使用了不安全的語法時,將會得到錯誤訊息 例如,不能使用指標運算 諸如 tempaltes, deterministic destruction 其他功能則是安全的
使用程式庫 使用 managed assembly : #using #using <System.Data.dll> 使用 COM 元件: #import #using <msxml4.dll> 使用 Standard C++ Library : #include #include <iostream>
C++/CLI 的標準化現況 C++/CLI 在 2005 年 12 月已經成為國際標準( ECMA 372 )
Reference Hello C++/CLI http://msdn.microsoft.com/msdnmag/issues/06/00/PureC/default.aspx ECMA-372 : C++/CLI Language Specification  http://www.ecma-international.org/publications/standards/Ecma-372.htm void Nish(char *szBlog) http://blog.voidnish.com/index.php?cat=2 The Code Project http://www.codeproject.com/managedcpp/#C%2B%2B%2FCLI
Thanks

More Related Content

What's hot (20)

PPTX
Effective Linux Development Using PetaLinux Tools 2017.4
Zach Pfeffer
 
PDF
How A Compiler Works: GNU Toolchain
National Cheng Kung University
 
PPTX
File Handling in Java Oop presentation
Azeemaj101
 
PDF
Embedded Linux Kernel - Build your custom kernel
Emertxe Information Technologies Pvt Ltd
 
PDF
from Source to Binary: How GNU Toolchain Works
National Cheng Kung University
 
PDF
Linux Kernel Overview
Anil Kumar Pugalia
 
PDF
Operator Overloading in C++
Mohammed Sikander
 
PPT
Borland C++Builder 進階課程
Sheng-Wei (Kuan-Ta) Chen
 
PPTX
C++ Builder 程式撰寫基礎 / C++ Builder Basic
YKLee3434
 
PPT
11 constructors in derived classes
Docent Education
 
PPTX
Linux PCI device driver
艾鍗科技
 
PDF
Q2.12: Debugging with GDB
Linaro
 
PDF
The linux networking architecture
hugo lu
 
PPTX
Revisit DCA, PCIe TPH and DDIO
Hisaki Ohara
 
ODP
Java Collections
parag
 
PPT
Introduction to gdb
Owen Hsu
 
PDF
LLVM 總是打開你的心:從電玩模擬器看編譯器應用實例
National Cheng Kung University
 
PDF
Java Course 8: I/O, Files and Streams
Anton Keks
 
PDF
Qemu JIT Code Generator and System Emulation
National Cheng Kung University
 
PDF
CNIT 127 Ch 5: Introduction to heap overflows
Sam Bowne
 
Effective Linux Development Using PetaLinux Tools 2017.4
Zach Pfeffer
 
How A Compiler Works: GNU Toolchain
National Cheng Kung University
 
File Handling in Java Oop presentation
Azeemaj101
 
Embedded Linux Kernel - Build your custom kernel
Emertxe Information Technologies Pvt Ltd
 
from Source to Binary: How GNU Toolchain Works
National Cheng Kung University
 
Linux Kernel Overview
Anil Kumar Pugalia
 
Operator Overloading in C++
Mohammed Sikander
 
Borland C++Builder 進階課程
Sheng-Wei (Kuan-Ta) Chen
 
C++ Builder 程式撰寫基礎 / C++ Builder Basic
YKLee3434
 
11 constructors in derived classes
Docent Education
 
Linux PCI device driver
艾鍗科技
 
Q2.12: Debugging with GDB
Linaro
 
The linux networking architecture
hugo lu
 
Revisit DCA, PCIe TPH and DDIO
Hisaki Ohara
 
Java Collections
parag
 
Introduction to gdb
Owen Hsu
 
LLVM 總是打開你的心:從電玩模擬器看編譯器應用實例
National Cheng Kung University
 
Java Course 8: I/O, Files and Streams
Anton Keks
 
Qemu JIT Code Generator and System Emulation
National Cheng Kung University
 
CNIT 127 Ch 5: Introduction to heap overflows
Sam Bowne
 

Viewers also liked (18)

PPTX
認識 C++11 新標準及使用 AMP 函式庫作平行運算
建興 王
 
PDF
Spring boot 5장 cli
Choonghyun Yang
 
PDF
Spring boot 공작소(1-4장)
Choonghyun Yang
 
PPT
開放原始碼的回收與再利用
建興 王
 
PPT
開發實用創新的 Android 應用程式
建興 王
 
PPTX
T69 c++cli ネイティブライブラリラッピング入門
伸男 伊藤
 
PPT
lwdba – 開放原始碼的輕量級資料庫存取程式庫
建興 王
 
PPT
IKVM.NET 深入敵營的 Java
建興 王
 
PPT
在雲端上啜飲爪哇
建興 王
 
PPT
從 Java programmer 的觀點看 ruby
建興 王
 
PPT
「沙中撈金術」﹣談開放原始碼的推薦系統
建興 王
 
PPTX
全文搜尋引擎的進階實作與應用
建興 王
 
PDF
ZeroFormatterに見るC#で最速のシリアライザを作成する100億の方法
Yoshifumi Kawai
 
PDF
Photon Server Deep Dive - PhotonWireの実装から見つめるPhotonServerの基礎と応用
Yoshifumi Kawai
 
PDF
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...
Yoshifumi Kawai
 
PPTX
RuntimeUnitTestToolkit for Unity
Yoshifumi Kawai
 
PDF
NextGen Server/Client Architecture - gRPC + Unity + C#
Yoshifumi Kawai
 
PDF
ZeroFormatter/MagicOnion - Fastest C# Serializer/gRPC based C# RPC
Yoshifumi Kawai
 
認識 C++11 新標準及使用 AMP 函式庫作平行運算
建興 王
 
Spring boot 5장 cli
Choonghyun Yang
 
Spring boot 공작소(1-4장)
Choonghyun Yang
 
開放原始碼的回收與再利用
建興 王
 
開發實用創新的 Android 應用程式
建興 王
 
T69 c++cli ネイティブライブラリラッピング入門
伸男 伊藤
 
lwdba – 開放原始碼的輕量級資料庫存取程式庫
建興 王
 
IKVM.NET 深入敵營的 Java
建興 王
 
在雲端上啜飲爪哇
建興 王
 
從 Java programmer 的觀點看 ruby
建興 王
 
「沙中撈金術」﹣談開放原始碼的推薦系統
建興 王
 
全文搜尋引擎的進階實作與應用
建興 王
 
ZeroFormatterに見るC#で最速のシリアライザを作成する100億の方法
Yoshifumi Kawai
 
Photon Server Deep Dive - PhotonWireの実装から見つめるPhotonServerの基礎と応用
Yoshifumi Kawai
 
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...
Yoshifumi Kawai
 
RuntimeUnitTestToolkit for Unity
Yoshifumi Kawai
 
NextGen Server/Client Architecture - gRPC + Unity + C#
Yoshifumi Kawai
 
ZeroFormatter/MagicOnion - Fastest C# Serializer/gRPC based C# RPC
Yoshifumi Kawai
 
Ad

Similar to Introduction to C++ over CLI (20)

PPTX
Dev307
建興 王
 
PDF
C++工程实践
Shuo Chen
 
PPTX
xwz 2010-10-31
carlxwz
 
PPTX
Linux c++ 编程之链接与装载 -基础篇--v0.3--20120509
tidesq
 
PPTX
C++模板与泛型编程
deer hope
 
PPTX
Metro Style Apps from C++ Developers' View
Eric ShangKuan
 
PPT
1 C入門教學
Sita Liu
 
PPTX
Hcsm lect-20120913
lusecheng
 
PPT
C#语言的演化
TerabyteX
 
PPTX
ES5 introduction
otakustay
 
PDF
竞赛中C++语言拾遗
乐群 陈
 
PPTX
Ecma script edition5-小试
lydiafly
 
PPT
ajax_onlinemad
Kitor23
 
DOC
2006年招聘试题
yiditushe
 
PPTX
Linux c++ 编程之链接与装载 -提高篇--v0.3--20120509
tidesq
 
PPTX
函数调用关系工具-2011-孙光福
Wu Liang
 
PPTX
TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式
Will Huang
 
PDF
VC++ Programming Training Lecture in Control Lab 301 of YSU
Gavin Gao
 
Dev307
建興 王
 
C++工程实践
Shuo Chen
 
xwz 2010-10-31
carlxwz
 
Linux c++ 编程之链接与装载 -基础篇--v0.3--20120509
tidesq
 
C++模板与泛型编程
deer hope
 
Metro Style Apps from C++ Developers' View
Eric ShangKuan
 
1 C入門教學
Sita Liu
 
Hcsm lect-20120913
lusecheng
 
C#语言的演化
TerabyteX
 
ES5 introduction
otakustay
 
竞赛中C++语言拾遗
乐群 陈
 
Ecma script edition5-小试
lydiafly
 
ajax_onlinemad
Kitor23
 
2006年招聘试题
yiditushe
 
Linux c++ 编程之链接与装载 -提高篇--v0.3--20120509
tidesq
 
函数调用关系工具-2011-孙光福
Wu Liang
 
TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式
Will Huang
 
VC++ Programming Training Lecture in Control Lab 301 of YSU
Gavin Gao
 
Ad

Introduction to C++ over CLI

  • 2. About Qing Education Ph.D. Candidate, Department of Computer Science, National Tsing-Hua University, Taiwan Research interests: distribute network management, mobile agent, VoIP, and p2p networking Software Development Skills Programming languages: 80x86 assembly, C/C++, Java, C# J2EE development and Web programming: EJB, JSP/Servlet Network programming: TCP/IP, socket programming Object Oriented Design/Programming Design Patterns and Software Architecture Distributed Network Management System Peer-to-Peer Networking Book Translation Thinking in Java 2nd Edition, in Traditional Chinese Essential C++, in Traditional Chinese
  • 3. Agenda 何謂 C++/CLI C++/CLI 中的型別宣告 Handle vs. Pointer Deterministic Destruction of C++/CLIS C++/CLI 中的陣列 C++/CLI 對 Property 的支援 C++/CLI 的四種編譯模式 Templates 及 Generics C++/CLI 的標準化
  • 4. 在 C++/CLI 出現前, .NET 上的 C++ 程式員恐怕只有一個字可以形容 悶
  • 5. .NET 上的 C++ 程式員為什麼悶? (1/2) 僅管有了 Managed Extension for C++ ,但卻存在一些對程式員的困擾 不夠流暢優雅的語法 例如:雙底線的關鍵字們 對 CLI 的支援不夠支接 例如:缺乏 for-each 語法,不支援 property C++ 與 .NET 之間的整合不夠好 例如:無法在 CLI 型別上使用 template ,也無法在 C++ 型別上運用 CLI 的機制,例如垃圾回收 *http://www.codeproject.com/managedcpp/cppcliintro01.asp
  • 6. .NET 上的 C++ 程式員為什麼悶? (2/2) 有兩種形式的指標: unmanaged 指標及 managed 指標,其用法及表示容易造成混淆 無法產生 verifiable 的程式碼
  • 7. 為什麼不學 C# 就好了? 多學一個程式語言 C++ 最佳化能力較強 C++ 具備 deterministic destruction (即使編譯為 MSIL ) C++ 程式員在 C++ 的特性支持下,生產力較高 STL template specialization
  • 8. 好消息是… .Net 上的 C++ 程式員不用再悶了
  • 9. C++/CLI 所帶來的拯救 優雅流暢的語法 對 CLI 的直接支援 property ,泛型,垃圾回收等機制全都有了直接的支援 在 unmanaged classes 上這些機制也都適用 妥善的橋接 .NET 與 C++ 透過 C++/CLI 編譯出來的程式碼,是 fully verifiable *http://www.codeproject.com/managedcpp/cppcliintro01.asp
  • 10. 何謂 C++/CLI ? C++ 所支援的靜態物件模型,目標放在對執行檔速度及大小的最佳化上 CLI 則為一支援動態元件編程模型的多階架構 C++/CLI 中的” /” ,代表 C++ 與 CLI 之間的 binding 何謂 C++/CLI 近似說法 1 : C++/CLI 將 C++ 靜態的物件模型繫結 (bind) 至 CLI 的動態元件模型 近似說法 2 : C++/CLI 將 .NET 編程模型整合進到 C++ 中 * Stanley B. Lippman , http://msdn.microsoft.com/msdnmag/issues/06/00/PureC/default.aspx
  • 11. C++/CLI 就是 C++ X CLI 確定性的記憶體管理 Template Native types STL 、 generic algorithms 指標 複製建構及指派 垃圾收集, finalizer 泛型 Reference 及 value types Interface Verifiability Security Properties, delegates, events 功能強力的 BCL C++ 的特點 CLI 的特點 C++/CLI 發揮 C++ 及 CLI 的相乘效果
  • 12. C++/CLI 的目標就是 無接縫式的整合 Unmanaged 及 Managed Code
  • 13. C++ 及 CLI 物件模型的比較 物件儲存空間類型多樣化 static, stack, 以及 heap 物件的生命期類型多樣化 static object 有著和程式相同的生命期 stack 上的 object ,則在和 scope({ … }) 的生命期相同 heap 上的 object ,則由程式員自行操控其生命期 物件建構及指派的深層拷貝模型 編譯時,原始碼中必須含括所有動用型別的資訊 物件儲存空間類型單純 Value type 儲存於 stack Reference type 儲存於 managed heap 上 物件的生命期具不確定性 Reference types 須倚靠垃圾收集器回收 物件的指派採淺層參考語義 編譯時,型別資訊由所使用型別的 metadata 提供 C++ 的靜態物件模型 CLI 的動態物件模型
  • 14. C++/CLI 中的型別宣告 在 C++/CLI 中可宣告下述型別 CLR 的 enumeration type enum class E {…} CLR 的 interface type interface class I {…} CLR 的 value type value class V {…} CLR 的 reference type ref class R {…} C++ 原生類別(過去 C++ 程式員所用) class N {…} 所宣告的型別 宣告語法
  • 15. C++ 與 CTS 型別的對應 N/A Boolean bool N/A Double long double N/A Double double N/A Single float UInt64 Int64 __int64 UInt32 Int32 long int UInt32 Int32 int, __int32 UInt16 Int16 short int Byte Sbyte char CTS Unsigned Type CTS Signed Type C++ Type
  • 16. 各型別的用途 原生型別 具備 native code 的語義及優點 即使被編譯成 MSIL 亦如此 Reference Type 可被垃圾收集器回收,提供簡便的記憶體管理模式 Value Type 輕量級的型別(例如像整數之類的型別) Interface Type 宣告 CLR 中的介面型別 Enumeration Type 宣告 CLR 中的列舉型別
  • 17. 例:在 C++/CLI 中宣告 Reference Type ref class Qing { public: void sayHello(); }; void Qing::sayHello() { Console::WriteLine(&quot;Hello!&quot;); } 多半宣告在 .h 檔裡 多半宣告在 .pp 檔裡
  • 18. Handle vs. Pointer C++/CLI 中將 native C++ 型別及 CLI 型別區分開來 C++/CLI 中同樣具備指向 CLI 型別的 ” 指標”,但採用了不同的符號來表示,同時賦予一個不同的名稱,以資區別 這個名稱就是 Handle (相對於 Pointer ) 這個符號就是 ^ (相對於 * ) 建構 native C++ 型別及 CLI 型別的關鍵字也已有所區隔 new :產生 native C++ 型別 gcnew :產生 CLI 型別( gc 意指 garbage collected ,垃圾回收之意)
  • 19. 透過 Handle 建構並運用 CLI 型別 Qing ^ qing = gcnew Qing(); qing->sayHello();
  • 20. 使用 Pointer 和 Handle 的差異 Pointer 用來在 native heap 中配置空間 語法: T* t = new T; 指標指向的位置是穩定的(不受 GC 影響),甚至可以被轉型為 int 倘若未自行釋放記憶體( delete ),則會產生 memory leak Handle 用來在 managed heap 中配置空間 語法: T^ t = gcnew T; GC 會自動釋放位於 managed heap 中的物件所佔用的空間 但程式員仍可針對 managed heap 上的物件呼叫 delete
  • 21. 不同的兩種物件生成及運用模式 *Kate Gregory, “Moving C++ Applications to the Common Language Runtime”   Use Native Heap    Use Managed Heap   Use Stack ^ and % always * and & never Verifiability d elete delete Free gcnew new Allocate % & Reference ^ * Pointer / Handle Managed Native
  • 22. 於 Native/CLI 型別中混用 Pointer/Handle (1/2) 在 CLI 型別中使用 Handle 在 CLI 型別中使用 Pointer ref class R { private: String ^str; } ref class R { private: std::string* str; }
  • 23. 於 Native/CLI 型別中混用 Pointer/Handle (2/2) 在 Native 型別中使用 Handle gcroot<T> 是用來包裝 System.Runtime.InteropServices.GCHandle 的一個 template class *http://www.codeproject.com/managedcpp/ijw_unmanaged.asp class N { private: gcroot<String^> str;; }
  • 24. Tracking Reference Operator % & 之於 pointer ,相當於 % 之於 handle R1 ^pr1 = gcnew R1(); R1 %r1 = * pr1; Console::WriteLine(r1 . ToString()); 不再是 -> 同樣使用 *
  • 25. Tracking Reference 的效應 array<String^>^ arr = gcnew array<String^>(3); int i = 0; for each(String^% s in arr) s = gcnew String(i++.ToString()); for each(String^ s in arr) Console::WriteLine(s); 執行結果: 0 1 2 array<String^>^ arr = gcnew array<String^>(3); int i = 0; for each(String^ s in arr) s = gcnew String(i++.ToString()); for each(String^ s in arr) Console::WriteLine(s); 執行結果:
  • 26. CLI 的 Non-Deterministic Finalization CLI 的垃圾回收機制,會在記憶體傾向不足時,將不再使用被物件佔用的記憶體空間回收再用 當物件佔用的記憶體空間確定被回收前的一刻,該物件的 Finalize() 會被呼叫,此即為 finalization (終始化)動作 Finalization 執行的時機及是否會被執行任誰都說不得準 所以被稱為 non-deterministic finalization
  • 27. Disposal 對於記憶體資源而言, non-deterministic finalization 不成問題 但對非記憶體資料(例如資料庫 、 檔案), 面對 non-deterministic finalization 的程式員得多費心才能使程式如預期的運作 對 .NET 而言,慣例上清理此類資料的動作,會定義於名為 Close() 或 Dispose() 的方法中 但這麼一來,程式員得自行呼叫 Close() 或 Dispose() 來進行清理動作
  • 28. Deterministic Destruction C++/CLI 除了 CLI 上原先就有的 finalizer 之外,還提供了 destructor. ref class R1 { public: R1() {} ~R1() {} protected: !R1() {} }; constructor destructor finalizer * 注意: C++/CLI 使用了 C# 中用來表示 Finalizer 的符號來表示 Destructor
  • 29. Finalizer vs. Destructor C++/CLI 中的 Destructor 最終會被編譯成為 Dispose() ,如果用 C# 的相對應程式碼來看的話,會像是: GC::SuppressFinalize() 會要求系統不要呼叫物件的 finalizer() ,避免物件被清理兩次 public void Dispose()//IDisposable::Dispose { GC.SuppressFinalize(this); } *http://www.codeproject.com/managedcpp/cppclidtors.asp *http://msdn2.microsoft.com/en-us/library/system.gc.suppressfinalize.aspx
  • 30. Why SuppressFinalize? public class FileStream : Stream { public override void Close() { // Clean up this object: flush data and close file … // There is no reason to Finalize this object now GC.SuppressFinalize(this); } protected override void Finalize() { Close(); // Clean up this object: flush data and close file } // Rest of FileStream methods go here … } *http://www.codeproject.com/managedcpp/cppclidtors.asp 如果程式員自行呼叫了 Close() , 但 GC 又呼叫了 Finalize() 便會引發 Close() 被叫用兩次
  • 31. 自動進行的 Disposal { SqlConnection conn(connString); } constructor 會被呼叫 destructor 會被自動呼叫 { SqlConnection ^pConn = gcnew SqlConnection(connString); } constructor 會被呼叫 之後就要等待 GC 動作了
  • 32. C++/CLI 中的陣列 使用 Managed Heap 的 Managed Array ,其基礎型別皆為 System::Array 使用 C++/CLI 的陣列時,可以想像存在一個虛擬的 template http://www.codeproject.com/managedcpp/cppcliarrays.asp namespace stdcli::language { template<typename T, int rank = 1> ref class array : System::Array {}; }
  • 33. 陣列定義語法 一維陣列語法 多維度陣列語法 array<String ^> ^ strArray = gcnew array<String ^>(10); for(int i=0;i<strArray->Length;i++) { strArray[i] = &quot;&quot;+i; Console::WriteLine(strArray[i]); } array<String ^, 3> ^ strArray = gcnew array<String ^, 3>(4, 3, 2); 維度 每個維度的長度
  • 34. 陣列的初始化 array<String^>^ strarr = gcnew array<String^> {“String1&quot;, “String2&quot;}; array<String^>^ strarr2 = {“String1&quot;, “String2&quot;}; array<Object^,2> ^ objarr = {{“String1&quot;, 1}, {“String2&quot;, 2}};
  • 35. 參數陣列 C++/CLI 支援參數陣列,參數陣列必須是最後一個參數 用…來標示參數陣列 void testParamArray(String ^s, ... array<String ^>^ params) { Console::WriteLine(s+&quot;: &quot;); for(int i=0;i<params->Length;i++) Console::WriteLine(params[i]); } int main(array<System::String ^> ^args) { testParamArray(&quot;Hello&quot;, &quot;qing&quot;); testParamArray(&quot;Hello&quot;, &quot;qing&quot;, &quot;chrisma&quot;); }
  • 36. Property 的語法 ref class UserAccount { public: property String^ ID { String^ get(){return id;} virtual void set(String^ value){id = value;} } private: String^ id; }; 就和 C# 的定義方式類似
  • 37. Index Property 的語法 ref class OnlineUserList{ public: property UserAccount^ User[int] { UserAccount^ get(int idx){return (UserAccount^) alUser[idx];} } OnlineUserList() { alUser = gcnew System::Collections::ArrayList(); } // … private: System::Collections::ArrayList ^alUser; };
  • 38. Refernece Type 允許單一繼承多重實作 ref class R abstract {}; public ref class R2 : R, IClone, IComparable, IDisposable, IEnumerable { }; 所有 reference type 都繼承自 System::Object 最多繼承一個類別,但可以實作多個介面
  • 39. Exception Handling try { throw gcnew Exception(&quot;qing&quot;); } catch(System::Exception^ e) { Console::WriteLine(e->StackTrace); }
  • 40. CLR 編譯模式:共有四種可供選擇 Mix( /clr) 包含 managed/unmanaged code Pure( /clr:pure ) 僅包含 managed code 但仍可使用 #include 並呼叫原生 API Verifiable( clr:safe) 僅包含 verifiable code Managed Extensions for C++( clr:oldSyntax ) 用來編譯舊式的程式碼
  • 41. 在 VS 2005 中選擇編譯模式
  • 42. 編譯模式之間的關連性 Native CLR Code Data Machine Code CLR Data / Types Native Data / Types MSIL Code Mixed C++ /clr Native C++ Verifiable C++ /clr:safe Pure C++ /clr:pure
  • 43. CLR 編譯模式帶來的應用 在 C++ 應用程式中直接使用 BCL 或以 .NET 寫成的 library 大幅提高生產力 將 native code 的功能,以 .NET 物件模型的方式對外提供 便於其他 .NET 應用程式使用( ASP.NET )
  • 44. 決定 Managed/Unmanaged 的交界處 C++ managed C++ CRT, STL, etc One call to foo() Hundreds of calls C# or C++ managed C++ CRT, STL, etc One call to foo() Hundreds of calls C# C++ CRT, STL, etc Hundreds of calls C++ One call to foo() One call * Kate Gregory, “ Moving C++ Applications to the Common Language Runtime”
  • 45. C++/CLI 支援 Template template<typename T1, typename T2> class NativeData { public: NativeData(T1 t1) { m_t1 = t1; } void DoStuff(T2 t2) { //... } private: T1 m_t1; }; *http://www.codeproject.com/managedcpp/cppcligenerics.asp
  • 46. Tempalte 採用 Lazy Constraint (1/2) template<typename T> class Native { public: void Start(int x) { T* t = new T(); t->Bark(x); t->WagTail(); delete t; } }; 如何確定 t 有 Bark() 及 WagTail() 兩 methods 呢? *http://www.codeproject.com/managedcpp/cppcligenerics.asp
  • 47. Tempalte 採用 Lazy Constraint (2/2) Native<NativeDog> d1; d1.Start(100); Native<NativePig> d2; d2.Start(100); 引發編譯器錯誤: error C2039: 'Bark' : is not a member of 'NativePig' *http://www.codeproject.com/managedcpp/cppcligenerics.asp
  • 48. C++/CLI 支援 Generics generic<typename T1, typename T2> ref class GenericData { public: GenericData(T1 t1) { m_t1 = t1; } void DoStuff(T2 t2) { //... } private: T1 m_t1; }; *http://www.codeproject.com/managedcpp/cppcligenerics.asp
  • 49. Generics 採用 Subtype Constraints (1/3) generic<typename T> where T:IDog ref class GenRef { public: void Start(int x) { T t = Activator::CreateInstance<T>(); t->Bark(x); t->WagTail(); delete safe_cast<Object^>(t); } }; 透過限制 T 必須實作的介面來進行約束 *http://www.codeproject.com/managedcpp/cppcligenerics.asp
  • 50. Generics 採用 Subtype Constraints (2/3) ref class ClrDog : IDog { public: virtual void Bark(int Loudness) { Console::WriteLine(&quot;ClrDog::Bark {0}&quot;,Loudness); } virtual void WagTail() { Console::WriteLine(&quot;ClrDog::WagTail&quot;); } }; *http://www.codeproject.com/managedcpp/cppcligenerics.asp
  • 51. Generics 採用 Subtype Constraints (3/3) GenRef<ClrDog^> g1; g1.Start(100); *http://www.codeproject.com/managedcpp/cppcligenerics.asp
  • 52. 使用 Reference Types 於 Template template<typename T> class CLR { public: void Start(int x) { T^ t = gcnew T(); t->Bark(x); t->WagTail(); delete t; } }; CLR<ClrDog> g2; g2.Start(100)
  • 53. 將 Template 宣告為 Reference Type template<typename T> ref class CLR2 { public: void Start(int x) { T^ t = gcnew T(); t->Bark(x); t->WagTail(); delete t; } }; CLR 2 <ClrDog> g 3 ; g 3 .Start(100) Console::WriteLine(g3.GetType()->Name); 執行結果: ClrDog::Bark 100 ClrDog::WagTail CLR2<ClrDog>
  • 54. Generics Functions generic<typename T> where T:IDog void DoAll(T t) { t->Bark(0); t->WagTail(); } *http://www.codeproject.com/managedcpp/cppcligenerics.asp
  • 55. Template vs. Generics Templates are instantiated at compile-time with the source code. The type checking of a template are performed at the point where the template is defined and instantiated . Tempaltes allow specialization. Templates allow non-type parameters. Templates use &quot; lazy structural constraints &quot;. Generics are instantiated at run-time by the CLR. The type checking of a generic is peformend at the point where the generic is defined . Generics are cross-language . Generics do not allow specialization. Generics do not allow non-type parameters. Generics use subtype constraints . *http://blogs.msdn.com/branbray/archive/2003/11/19/51023.aspx
  • 56. Verifiable C++ 以 /clr:safe 編譯,將會試著產生 verifiable assembly 若使用了不安全的語法時,將會得到錯誤訊息 例如,不能使用指標運算 諸如 tempaltes, deterministic destruction 其他功能則是安全的
  • 57. 使用程式庫 使用 managed assembly : #using #using <System.Data.dll> 使用 COM 元件: #import #using <msxml4.dll> 使用 Standard C++ Library : #include #include <iostream>
  • 58. C++/CLI 的標準化現況 C++/CLI 在 2005 年 12 月已經成為國際標準( ECMA 372 )
  • 59. Reference Hello C++/CLI http://msdn.microsoft.com/msdnmag/issues/06/00/PureC/default.aspx ECMA-372 : C++/CLI Language Specification http://www.ecma-international.org/publications/standards/Ecma-372.htm void Nish(char *szBlog) http://blog.voidnish.com/index.php?cat=2 The Code Project http://www.codeproject.com/managedcpp/#C%2B%2B%2FCLI