使用C++/CLI
認識C++/CLI
其實從這個名字就可以簡單概括出C++/CLI的特點:首先它是一門C++語言,其次它遵循了CLI(Common Language Infrastructure)規范。簡單來說CLI是微軟提出的定義了一種可執行代碼和編程模型的規范,它由CTS(Common Type System)、CLS(Common Language Specification)、IL(Intermediate Language)等幾個部分組成。所以C++/CLI是一門用C++實現CLI規范的語言,而C#、VB等.NET語言也是CLI規范下的語言,因此這項技術使得C++與.NET語言之間的相互調用非常高效且自然。
為什么要使用C++/CLI
如果不使用C++/CLI,那么C++與.NET語言之間只能通過標準C接口的方式互相調用(P/Invoke)。這種方式本質是C語言和其它編程語言之間的調用方式,C/C++、C#、Java、Rust、Python等語言之間都可以通過導出C接口的方式互相調用。這是一種比較原始的技術,在C++和C#混合編程的場景下,并不是好的解決方案。
我總結了P/Invoke方式與C++/CLI方式之間幾方面的對比:
| 特點 | P/Invoke | C++/CLI |
| 調用方式 | 必須先使用extern聲明方法,再調用。且在聲明時還需要標識DllImport、EntryPoint等調用信息 | 與調用自有方法一樣,毫無跨語言調用的痕跡 |
| 數據類型 | 參數類型和返回類型只支持數值、字符等基本類型,因為本質是C語言接口 | 有CTS系統支撐,支持類、結構、枚舉、事件等復雜數據結構 |
| 代碼復用 | 只能調用方法。C是面向過程的,沒有類的概念,自然也沒有靜態和實例的概念 | CLI是面向對象的,可以復用類,實例方法的。 |
C++/CLI入門
通過一個簡單的示例來介紹一下C++/CLI
Employee.h
public ref class Employee
{
public:
Employee(System::String^ fullName);
Employee(System::String^ fullName, System::DateOnly hireDate);
System::String^ Department;
System::String^ FullName;
System::DateOnly HireDate;
/// <summary>
/// 獲取工齡
/// </summary>
/// <returns></returns>
System::DateOnly GetServiceTime();
};
這就是一個簡單的C++/CLI托管類。下面解釋一下C++/CLI中特殊的語法:
1、ref(reference)標記該類是CLI規范下的托管類,ref標記是為了區分標準C++中的class
2、^標記表示對托管對象的引用,面向對象中的“引用”類似于C++中的“指針”。
3、System::String、System::DateOnly都是.NET中的類型,托管類中只能使用System中的類型,不能使用指針、wchar_t等C++類型。
因為托管類的內存由垃圾回收機制處理,非System中的類型不能被正確處理,且托管類是與.NET之間相互使用的類,.NET是不認識C++中的類型的。
4、System::DateOnly是值類型,所以不需要使用^,在CLI中值類型的傳遞規則是復制一份相同的數據。當然也可以加^,表示對值類型對象的引用。
Employee.cpp
Employee::Employee(System::String^ fullName, System::DateOnly hireDate) {
FullName = fullName;
HireDate = hireDate;
}
Employee::Employee(System::String^ fullName) {
FullName = fullName;
Department = gcnew System::String("臨時");
}
gcnew是為了區分new引入的,專門用來創建托管對象。gcnew創建對象然后^的應用指向該對象。
C++/CLI中的概念對于熟悉.NET的人來說不難理解。
在.NET中所有對象都可以分為引用類型和值類型,值類型包括基礎的數字(int,double等)、字符(char)、枚舉、結構(struct)、true/false。除此之外的類(class)、字符串(string)、數組(arrary)、委托(delegate)等都是引用類型。值對象的創建直接通過=賦值即可,引用類型對象只能通過new創建。參數傳遞時引用對象傳遞引用,值對象復制一份相同數據到棧。
在C++/CLI中你可以使用ref class,也可以使用原本的class,但是與.NET交互的類只能是ref class。
不只是膠水語言
很多人把C++/CLI只看成是連接C++和.NET的膠水語言,其實不然。
應該把它看成一門獨立的語言,在C++/CLI中你既可以編寫托管代碼,也可以編寫標準C++代碼,你可以單獨使用它編寫一個程序。
浙公網安備 33010602011771號