青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

C++ Programmer's Cookbook

{C++ 基礎} {C++ 高級} {C#界面,C++核心算法} {設計模式} {C#基礎}

C/C++ 應用程序路線圖(msdn)

發布日期: 11/26/2004 | 更新日期: 11/26/2004

Kate Gregory
Gregory Consulting

適用于:
Microsoft Visual C++
Microsoft.NET 公共語言運行庫 (CLR)
C++/CLI 擴展
Microsoft .NET Framework
WinFX

摘要: 本文針對(至少到目前為止)在新的和現有的應用程序中還沒有以Microsoft .NET Framework 為目標開發平臺的 C++ 程序員。 文中為如何轉向 .NET Framework 而且避免拋棄現有代碼中的投資提供了一些指導,并闡述了為什么應該考慮轉向 .NET Framework ,這不僅適用于新的開發工作,對現有應用程序亦然。

*
本頁內容
為什么要使用公共語言運行庫? 為什么要使用公共語言運行庫?
相關語言回顧 相關語言回顧
理解 .NET 上的 C++ 理解 .NET 上的 C++
托管和非托管類型 托管和非托管類型
依然是 C++ 依然是 C++
混合托管和本機開發 混合托管和本機開發
.NET 路線圖 .NET 路線圖
小結 小結

為什么要使用公共語言運行庫?

Microsoft 總是支持程序員從他們自己的代碼中訪問操作系統功能。 在 Windows 的早期,我們從 C 語言程序中使用 Windows API ,進行函數調用(比如 GetMessage(), TranslateMessage(), 等等)以達到目的。 隨著時間變遷, Windows 功能開始使用 COM 組件比如 Shell 來公開。 為了充分利用 Windows 完整的功能,程序員學會了 COM 的概念,創建了許多 COM 應用程序。 這種演變仍在繼續,如今,為了充分發揮 WinFX 的功能,你的應用程序應該使用公共語言運行庫,也稱 CLR 了。 WinFX 是一種托管 API ,設計成從為 CLR 編寫的托管應用程序中調用,通過 WinFX ,你的應用程序能夠利用 Avalon 和 Indigo 這樣的新技術的功能。 WinFX 是基于 .NET 對象模型的。

訪問操作系統功能當然不是 CLR 的唯一優勢: .NET Framework 提供了比 COM 和 DCOM 更佳而且更簡單的組件模型。 .NET Framework 中包含的托管代碼庫所能提供的功能,遠遠超出了操作系統本身,這使我們能夠將精力放在應用程序中專門解決特定問題的部分,而用不著再去處理許多人已經解決過的問題。 同樣,可以構建一個基于組件的解決方案,而不需涉及以前與 COM 和 DCOM 部署相關的那些困難。

相關語言回顧

這是否意味著你應該重新編寫所有應用程序呢? 當然不是。 如果原來的應用程序是用 C++ 編寫的,現在不對代碼做任何改變就可以針對 CLR 進行編譯。 重新編寫會帶來巨大風險,因為在將程序移植到另一種語言比如 C# 時,可能在能夠工作的代碼中引入錯誤。 重新編寫和轉換代碼所能期望的最佳值,也不過是實現與以前同樣的功能。 如果想以 CLR 為目標平臺根本不需要這樣做。 相反,你的時間和精力可以花在使用新的系統功能和擴展應用程序的功能上。

自 .NET Framework, CLR 和 C# 發布以來的幾年中,許多開發人員都對 Microsoft 的 C++ 計劃感到驚奇。 有些人推測 C# 將取代 C++ ,事實上當然并非如此。 C# 是一種比 C++ 更容易學習的語言,它提供了訪問 CLR 功能的途徑。 對于已經了解 C++ 的人來說,要訪問 CLR 的功能,無需學習其他語言, C++ 具備 C# 中沒有的功能,因此轉向 C# 實際上將會喪失一些能力。

Microsoft Visual C++ 的每個版本與標準的兼容性都比前一版更好,當前版本 Visual C++ .NET 2003 ,大約與 ISO C++ 標準達到了 98% 兼容。 這一版本中訪問 CLR 功能的關鍵字都以雙下劃線開始,因此不會干擾與標準的兼容性。 雖然這種方式可行,但是很笨拙,而且不夠直觀。 Visual C++ 2005 中將包含一個新的 C++ 到 .NET 的綁定,該綁定正在以 C++/CLI 的名稱進行標準化。 這一修訂包括當前 C++ 標準中沒有的關鍵字,但是同樣不會干擾符合標準的 C++ 程序,因為它們遵守 ISO C++ 的標準擴展機制。 C++/CLI 擴展的國際標準正在由 ECMA 制定,最終將提交給 ISO 。 與今天的 C# 一樣, C++/CLI 將被標準化,因此 Microsoft 將不會是 C++/CLI 編譯器的唯一來源。 Visual C++ 2005 現在已經處于 beta 版,因此我們可以立即探討這些新的擴展。 在這篇白皮書中,我們將在代碼示例中使用新的 C++/CLI 語法。 ( CLI 代表的是公共語言基礎結構,是 .NET Framework 的標準化部分,包括 .NET 公共語言運行庫。)

理解 .NET 上的 C++

當你編寫在 CLR 上運行的代碼時,你所編寫的就是托管代碼。 標準 C++ 代碼,也就是能夠在任何符合標準的 C++ 編譯器上編譯的代碼,可以編譯成非托管(本機)代碼或者編譯成 MSIL : 只需使用一個編譯器開關即可。 指定 /clr 選項,編譯器就會生成 MSIL ,一個在 CLR 上運行的程序集。 使你的代碼成為托管的就是使用 編譯器選項。 不需要使用任何特殊的關鍵字或者太多改變代碼(如果需要改變的話),就能夠通過 /clr 選項干凈利索地進行編譯。

編寫了托管代碼之后,就可以(如果你愿意)使用 CLR 功能了,比如基類庫: 這是能夠實現 XML 操作、加密解密、數據訪問等等功能的強大的類庫。 非托管代碼,即沒有使用 /clr 選項編譯的代碼,就無法聲明托管類的實例,并按托管代碼的方式直接調用它們的方法。 可以通過 .NET Interop 從非托管代碼中訪問托管代碼,該技術能夠使 .NET 對象看上去像是一個 COM 組件。 這種方式與將代碼編譯成托管的,并直接調用托管代碼相比,肯定要慢。

無論是否使用基類庫(和其他托管庫),你仍然可以用 C++ 編寫程序,仍然擁有 C++ 賦予你的所有功能和靈活性。 可以使用模板,編寫操作符重載,創建內聯函數,等等。 編譯為 MSIL 并不會阻止你使用任何 C++ 功能。 比如說,多重繼承被排除在外不是因為代碼編譯為 MSIL 了,而只是因為你編寫的是托管代碼而已。

托管和非托管類型

一個普通的 C++ 類,就是編程語言入門課程中教授的那種,將定義一個非托管類型:

class A
{
private:
   int x;
public:
   A(int xx): x(xx) {}
};

無論是否帶 /clr 選項編譯代碼(托管還是非托管代碼),這都是一個非托管類型,也俗稱為非托管類或者非托管數據。 這個類的實例可以分配在堆棧中,這也是編程語言入門課程中教授的內容:

A something(3);

它們還可以在本機或者非托管堆中創建:

A* otherthing = new A(4);

程序員然后還必須記住清除非托管堆中的對象,使用 delete 操作符:

delete otherthing;

無論是哪一種方式,都不會涉及垃圾回收器,即使代碼編譯為 MSIL ,而且應用程序運行在運行庫上。

但是你也可能需要編寫托管類型(也稱托管類或者托管數據)。 這些類型可以從其他程序集中調用,其他運行在運行庫上的托管代碼,無論其他程序集是用什么語言編寫的。 用 C# 、用 Visual Basic .NET 或者用你沒有聽說過但是碰巧能編譯成 MSIL 的語言編寫的代碼,都可以使用你的托管類型。 這種交互是由運行庫托管的,而且在大多數情況下,你的代碼和其他程序集所創建的那些類型實例的生存期也是由運行庫托管的。

這些托管類型是第一級的 .NET 對象。 用 C++/CLI 創建托管類型,可以采取一種自然的語法,與傳統 C++ 區別不大:

ref class R
{
private:
   int x;
public:
   R(int xx): x(xx) {}
};

這個類定義使用了一個空格關鍵字——僅包含一個空格的關鍵字。 從技術上說, C++/CLI 中并沒有 ref 關鍵字,而只有 ref class 關鍵字。 這意味著你可以使用名為 ref 的變量而不會引起沖突。 而且這個類 R 可以被用 C# 或者 Visual Basic .NET 或者其他支持 .NET 的語言編寫的代碼所使用。 可以用 C++/CLI 編寫一個類庫,使用你作為一位 C++ 程序員多年形成的技術和技巧,然后將這個庫用在根本沒有使用 C++ 編寫的應用程序中。 它們只需要是運行在 CLR 上的應用程序即可。

依然是 C++

轉向 CLR 并不意味著要轉向 C# 。 許多 C++ 開發人員在 C# 發布時轉向了 C# 。 其原因多種多樣: C# 的向導和設計器支持更好,而且管理層經常會支持新語言,僅僅是因為它新,而一些開發人員并沒有認識到托管應用程序也能夠用 C++ 創建。 但是許多開發人員都拒絕這種轉向,甚至某種程度上完全拒絕轉向 CLR 。 拒絕的理由中常見的主題是: “我喜歡 C++ 。” C++ 具有其他語言不具備的功能,比如真正的確定性析構和模板。 選擇用 C++ 編寫托管代碼時,你可以獲得所有 C++ 的功能和所有 CLR 功能: 可謂魚與熊掌兼得。

確定性析構

在其他支持 .NET 的語言比如 Visual Basic .NET, C# , 或者 Visual C++ .NET 2003 C++ 托管擴展中,實例的位置取決于要創建的類型。 如果創建的是一個托管類型的實例,它將創建在托管堆中:

Dim o as new R(3)  ' VB.NET
R o = new R(3); // C#
R* o = new R(3); // managed extensions for C++

實例(在所有這些例子中都是 o )使用的內存是由運行庫托管的,可以被垃圾回收器清除或者重新組織。

相反,如果你創建的是一個值類型的實例,在所有三種語言中,實例都是在堆棧中創建的:

Dim i As Int32 = 7  ' VB.NET
int i = 7; // C#
int i = 7; // managed extensions for C++

只有在 C++/CLI 中你能夠獲得自由,自行決定在哪里創建對象,是否想讓實例的內存由運行庫托管。 你可以在托管堆中創建一個引用類的實例(即前面用 ref class 關鍵字定義的那個實例),如下:

R^ o = gcnew R(3);  // C++/CLI

如果愿意,可以在堆棧中創建實例:

R os(3);

o 和 os 之間的區別在它們的生存期上,或者說得更加具體一些,是對它們生存期的控制力。 如果編寫的是托管代碼,你可能不會介意放棄對內存的控制權,反而愿意信任運行庫和垃圾回收器為你管理內存。 但是開發人員仍然需要操心與內存無關的清除工作: 比如關閉文件或者連接。 垃圾回收本身不足以處理你在應用程序中使用的所有資源。 在 C++ 中,這種與內存無關的清除通常是在析構函數中進行的。

托管堆中的對象是通過句柄 o 訪問的,當控制達到帶有 gcnew 的那一行時對象就開始存在。 未來某個時候, o 將超出控制范圍。 可能控制已經超過用 return 或者 exit 語句聲明它的代碼塊,可能代碼塊是 if, for, 或者 while 語句的謂詞而且控制已經以通常的方式離開,或者出現了異常。 無論原因如何, o 都將超出范圍。 這時候,事情變得有些復雜。 如果任何代碼都有句柄的副本,副本將到處都是,然后只要范圍中有句柄,對象就將繼續在托管堆中存在。 如果句柄對象應該回收了,但是回收的準確時間并不知道,因此何時運行析構函數是未知的。 這取決于應用程序施加的內存壓力數量等等因素。

對于堆棧中的對象 os ,情況就大大不同了。 在超出范圍后(按照使 o 超出范圍的同樣情況),對象的一切就結束了。 它的析構函數,如果有的話,將在 os 離開范圍后立即運行。 你可以準確地知道與內存無關的清除何時發生,而且能夠盡快發生。 這就是所謂確定性析構。

順便提及, os 實例(我們認為它在堆棧中)實際上使用的是托管堆上的內存(依然是由垃圾回收器托管的)。 析構函數并不回收該實例使用的內存;它關心的是與內存無關的清除。 引用類型只能模擬為在堆棧中。 如果你已經習慣不管內存管理,并信任垃圾回收器處理一切,這種模擬是非常理想的。

C# 中的 using 構造提供了類似的能力,但是 C++ 中的自動范圍更簡單: 編寫的代碼更少,而且不會忘記。 在 C++ 中的析構函數和可以用其他語言編寫的托管類型中的 Dispose() 方法之間有很好的對應關系: 實際上它們是相同的。 當 C# 代碼使用你的托管類型并調用 Dispose() 時,實際上運行的就是析構函數。 如果 C++/CLI 代碼使用一個不是用 C++ 編寫的托管類型,并在堆棧中創建它,當實例超出范圍時,就不會運行一個 C++ 析構函數,而是運行一個 Dispose() 方法。 對于 C++ 開發人員而言,這就是確定性析構。 這意味著我可以這樣編寫 C# 代碼:

{
   using( System::Data::SqlClient::SqlConnection conn
     = new System::Data::SqlClient::SqlConnection(connString) ) {
      // work with the connection in some way
      // including code that might throw an exception
      using( System::Data::SqlClient::SqlCommand cmd
        = new System::Data::SqlClient::SqlCommand(
              queryString, conn) ) {
         // work with the command
      // must write "using"s to call Dispose or Close
      }
   }
}

在 C++ 中,我可以編寫這樣的代碼:

{
   System::Data::SqlClient::SqlConnection conn(connString);
   // work with the connection in some way
   // including code that might throw an exception
   System::Data::SqlClient::SqlCommand cmd(queryString, %conn);
   // work with the command
   // don't call Dispose or Close explicitly
}

SqlConnection 和 SqlCommand 對象實現了 IDisposable ,但是 C++/CLI 程序員不需要記著調用 Dispose() 。 編寫代碼更少,不會遺忘,都是 C++ 中析構機制的自然優點。 使用 CLR 上的這一機制非常自然和直觀,而無需要求庫用 C++ 編寫或者實現析構函數。

模板

C++/CLI 中使我們能夠在堆棧中創建托管類型實例的因素,也使我們能夠在傳統 C++ 模板中使用托管類型:

set<String^>^ SetofStrings;
. . .
String^ s = "Hello World";
SetofStrings->insert( s );

這意味著使用托管類型(無論是你自己的還是來自基類庫)時, STL 中的一切都可以訪問。 C++/CLI 帶有一些輔助模板,包括 auto_close<> (這是一個智能指針的 Variant ,能夠調用它所包裝的實例的 Close 方法),和 marshal_as<> ,能夠轉換相關的類型比如 System::String 和 std::string 。

混合托管和本機開發

如果你還在猶豫是否用 /clr 選項重新編譯標準非托管 C++ 代碼,請不要煩惱! 在一個應用程序中混合和匹配托管和本機(非托管)代碼是非常直接的。

從托管代碼,你可以調用任何現有的非托管代碼,就像非托管到非托管似的。 包含頭文件,與庫連接之后,然后就一切就緒了。 你是調用一個老的 C 語言庫,一個 C++ 庫還是一個 COM API 都無關緊要。 你所調用的代碼使用了什么庫也無關緊要。 只需 #include 并如常繼續即可。 你的代碼可以在托管呼叫代碼和非托管目標代碼之間過渡,然后為托管代碼帶來最高性能的回報。 其他支持 .NET 的語言都沒有這樣的選擇。 這種功能,以前被稱為 It Just Works interop ,現在稱為 C++ Interop 。

從非托管代碼可以訪問所有托管類型,不過需要包裝為 COM 類型。 regasm 實用工具為托管類型生成和注冊類型庫,可以使用編譯器支持(比如 #import )從本機代碼中訪問組件。 這一選擇會影響性能: 可以改而選擇用 /clr 編譯呼叫代碼,并直接通過運行庫訪問托管類型。 為了保持 C++ 的理念,選擇由你決定。

.NET 路線圖

C++/CLI 為你提供了極大的余地,可以選擇如何訪問由 CLR (以及由 WinFX )提供的功能。 如果你要編寫一個新的應用程序,用 C++/CLI 編寫以 CLR 為目標平臺所具有的優點是不可抗拒的。 可以擁有可靠性,可以訪問重要的托管 API ,從托管庫中獲得極高的開發人員生產率,而又無需放棄訪問本機庫或者任何 C++ 范型。 進行這種決策簡直是再清楚不過了: 用 C++/CLI 為 Windows 編寫一個托管應用程序。

那么現有的應用程序怎么辦呢? 有些應用程序已經到了它們生存周期的末期: 你已經不想增加功能或者進行明顯改動了。 用戶不再指望它與其他應用程序集成。 像這樣的應用程序無需轉向 .NET 。 它們將在未來運行在 Microsoft Windows 代號 "Longhorn" 之上,因此可以不去管它們。

剩下的就是還沒有到生存期末期的現有應用程序了。 你想維護和增強這些應用程序,可能還計劃在增強中使用托管庫。 或者你可能愿意以 CLR 為目標平臺以減少大型分布式應用程序部署時的麻煩。 基本上,有三種選擇: 重寫,集成或者遷移。

重寫是風險最大的一種方式。 必須完整地閱讀代碼,找出 .NET 世界中有等效物的庫和構造。 例如,原來可能使用 MFC 構建 Windows 應用程序的用戶界面: 而今天 .NET 中的等效物是 Microsoft Windows 窗體,在 "Longhorn" 時代是 Avalon 。 可以使用 ADO 或者 MFC 數據訪問類處理數據: 而 .NET 的等效物是 Microsoft ADO.NET ,使用 DataSet 或者 DataReader 類。 尋找這些庫和構造的工作量是非常大的。 然后還要重新編寫應用程序的大部分,在此過程中還可能引入錯誤,所以還必須進行全面測試。 這都需要時間和成本,但是當工作全部完成,你將擁有一個現代的應用程序,全部用 C++/CLI 編寫,盡可能使用托管庫。

如果當前代碼基礎比較老,而且已經更新多次,或者你的開發團隊并不能很好地理解,但是它又必須以某種方式改進或者更新,那么重新編寫可能是最適合你的方式。 如果必須創建可以驗證的程序集以用于部分信任情況,可能也需要采取一些重新編寫的方式。 雖然對于大多數開發人員來說這一方式是第一計劃,但是實際上它應該是最后的選擇。 如果現在你的代碼很簡潔,文檔齊全,性能很好,應該盡可能拒絕進行重新編寫。

集成方式是將所有 .NET 庫(基類庫, WinFX, Indigo, Avalon, 等等)都視為要使用的新庫。 現有的代碼基礎保持不變,用使用這些新庫的新模塊擴展它。 可以將應用程序的主干代碼重新編譯為 MSIL ,直接調用運行庫中的新庫,并使用 C++ Interop 訪問老庫。 或者,可以將主干代碼保留為本機(非托管)代碼,使用 COM 可調用包裝來包裝托管類型,將它們公開給舊代碼。 進行一些性能測試有助于進行決策。 可以根據選擇用 /clr 編譯部分代碼基礎。

遷移方式處于上面兩個極端之間。 在你的應用程序已經分成多個組件或者層時最適合。 (巨大的單塊應用程序是非常難于維護的,因此無論如何都應該將應用程序組件化,但是這種重構也是一種形式的重新編寫,會帶來風險。) 然后可以將每個組件用公開托管類型的 C++/CLI 代碼包裝起來。 新的主干應用程序可以使用這些托管類型,新的托管類型也可以與 .NET 庫交互。 隨著時間推移,在包裝中的本機“核心”可以重新編寫為完全的托管代碼,只使用托管庫,如果有重要的性能原因或者代碼安全原因需要如此的話。

小結

無論進行何種開發: 從頭編寫一個新的應用程序,維護我們無需做太多工作的現有應用程序,或者使一個歷盡滄桑的老應用程序重新煥發青春, .NET Framework 都可以使你的工作更加簡單。 使用 C++/CLI 將應用程序與 CLR 集成,或者將應用程序遷移到 CLR ,都比將應用程序移植到 C# 更加可行。 C++/CLI 為我們提供了CLR 上 C++ 的功能和靈活性,提供了真正的確定性析構(即使是托管類型),提供了性能最高的交互操作。 對于任何要以 CLR 為目標平臺的開發應用程序的 C++ 程序員而言,這都是一種非常自然的選擇。

作者簡介

Kate Gregory 是一位 Microsoft 地區經理, Visual C++ MVP ,以及《 Microsoft Visual C++ .NET 2003 Kick Start 》一書的作者。 Gregory 咨詢公司為全北美提供咨詢和開發服務,專門利用最新技術從事軟件開發、集成項目、技術寫作、指導和培訓。

轉到原英文頁面

posted on 2005-12-15 09:23 夢在天涯 閱讀(1614) 評論(0)  編輯 收藏 引用

公告

EMail:itech001#126.com

導航

統計

  • 隨筆 - 461
  • 文章 - 4
  • 評論 - 746
  • 引用 - 0

常用鏈接

隨筆分類

隨筆檔案

收藏夾

Blogs

c#(csharp)

C++(cpp)

Enlish

Forums(bbs)

My self

Often go

Useful Webs

Xml/Uml/html

搜索

  •  

積分與排名

  • 積分 - 1811983
  • 排名 - 5

最新評論

閱讀排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
      <noscript id="pjuwb"></noscript>
            <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
              <dd id="pjuwb"></dd>
              <abbr id="pjuwb"></abbr>
              亚洲调教视频在线观看| 国产专区综合网| 亚洲精品国精品久久99热| 亚洲福利久久| 欧美精品在线一区二区| 亚洲视频电影图片偷拍一区| 一本一本久久| 国产日韩精品电影| 欧美激情精品久久久久久变态| 毛片一区二区三区| 亚洲视频中文字幕| 欧美一区二区三区久久精品| 伊人狠狠色丁香综合尤物| 亚洲国产日韩欧美| 国产精品乱码一区二区三区| 久久精品网址| 欧美日本亚洲视频| 久久精品国产第一区二区三区| 久久久精品视频成人| 一本大道久久精品懂色aⅴ| 亚洲网站视频| 亚洲国产一区在线| 亚洲一区欧美二区| 91久久午夜| 亚洲一级片在线观看| 亚洲国产精品va在看黑人| 亚洲视频大全| 亚洲国内精品在线| 午夜精品视频一区| 一区二区三区视频免费在线观看| 欧美一级理论片| 99xxxx成人网| 久久青草福利网站| 欧美一区二区三区在线看| 麻豆国产精品一区二区三区 | 美女精品视频一区| 亚洲影视九九影院在线观看| 久久久久成人网| 亚洲欧美视频在线观看| 欧美高清视频www夜色资源网| 欧美在线3区| 欧美日产国产成人免费图片| 久久久欧美一区二区| 欧美性大战久久久久久久蜜臀| 免费观看日韩| 国产一区二区三区四区hd| 99在线精品视频| 亚洲精品激情| 鲁大师成人一区二区三区| 久久国产精品99国产精| 国产精品萝li| 在线视频一区二区| 亚洲午夜激情在线| 欧美日韩国产小视频| 欧美激情91| 1024成人网色www| 久久久999精品| 久久精品国产亚洲精品| 国产日韩一区二区三区| 午夜精品影院| 蜜桃av久久久亚洲精品| 国产真实乱偷精品视频免| 午夜激情亚洲| 久久精品女人天堂| 国产婷婷色一区二区三区四区| 亚洲欧美激情四射在线日 | 欧美成人综合网站| 亚洲电影av在线| 日韩午夜一区| 欧美视频你懂的| 亚洲午夜黄色| 久久成人这里只有精品| 国产自产2019最新不卡| 久久夜色精品国产| 亚洲国产另类精品专区| 亚洲私拍自拍| 国产欧美日本一区视频| 久久av在线看| 亚洲福利小视频| 亚洲午夜久久久| 国产视频精品xxxx| 久久夜色精品国产欧美乱| 亚洲激情一区| 欧美一区二区精品| 亚洲大片精品永久免费| 欧美激情一区二区三区高清视频 | 99精品视频免费全部在线| 亚洲综合国产| 激情综合亚洲| 欧美日韩综合视频网址| 香蕉视频成人在线观看 | 中文日韩在线| 国产亚洲观看| 欧美精品电影| 午夜精品久久久久久久99水蜜桃 | 久久视频一区| 亚洲美女一区| 老司机精品导航| 亚洲视频福利| 一区免费在线| 国产精品激情偷乱一区二区∴| 性欧美8khd高清极品| 亚洲国产精品一区二区www| 性欧美大战久久久久久久免费观看| 黄色国产精品一区二区三区| 欧美日产一区二区三区在线观看| 亚洲一区二区三区国产| 欧美激情视频网站| 欧美自拍偷拍午夜视频| 一本色道久久| 亚洲福利专区| 国产日韩欧美夫妻视频在线观看| 欧美激情综合在线| 久久久久久久久久久久久久一区 | 久久精品免费| 久久久综合网站| 国产亚洲综合精品| 欧美日本高清一区| 久久亚洲综合色| 性8sex亚洲区入口| 亚洲视频中文字幕| 亚洲人成在线观看| 欧美高清视频一区二区三区在线观看 | 亚洲图片欧美午夜| 亚洲精品国产精品乱码不99| 欧美高潮视频| 久久色中文字幕| 欧美一区二区三区免费在线看 | 国模私拍一区二区三区| 国产精品毛片| 国产精品s色| 欧美视频一区在线| 欧美日韩一区在线观看视频| 欧美肥婆在线| 欧美激情国产精品| 欧美国产一区在线| 你懂的国产精品永久在线| 久久影视精品| 久久夜色精品亚洲噜噜国产mv | 午夜一区在线| 欧美一区二区网站| 欧美一区二区视频在线| 欧美一区日本一区韩国一区| 午夜精品久久久久久久99黑人| 亚洲——在线| 欧美中文字幕在线播放| 久久精品官网| 巨乳诱惑日韩免费av| 猫咪成人在线观看| 欧美人成在线| 欧美视频三区在线播放| 国产精品毛片a∨一区二区三区|国| 国产精品免费一区豆花| 国产精品一区二区久久精品| 国产三区精品| 亚洲国产成人午夜在线一区| 亚洲精品视频在线播放| 亚洲婷婷综合色高清在线 | 亚洲毛片在线观看| 这里只有精品视频| 午夜欧美大片免费观看| 久久人人97超碰人人澡爱香蕉| 蜜臀av在线播放一区二区三区| 欧美国产日韩二区| 日韩一区二区精品视频| 午夜精品久久久久久久男人的天堂| 久久经典综合| 欧美日韩日日骚| 狠狠干狠狠久久| 99re6热在线精品视频播放速度| 亚洲一区二区三区视频播放| 久久一区视频| 亚洲美女色禁图| 久久精品女人| 欧美日韩亚洲在线| 黄色成人av网| 亚洲男人天堂2024| 美国三级日本三级久久99| 日韩一级在线观看| 久久久欧美一区二区| 欧美调教视频| 亚洲国产毛片完整版 | 尤物九九久久国产精品的分类| 亚洲精品欧美激情| 久久九九国产精品| 日韩西西人体444www| 久久激情久久| 国产精品美女久久久浪潮软件| 亚洲第一页中文字幕| 欧美一区二区三区在线观看| 国产精品每日更新| 欧美激情精品久久久久久蜜臀 | 亚洲精品在线观看免费| 久久精品在线免费观看| 日韩一区二区免费看| 免费中文字幕日韩欧美| 韩国一区二区在线观看| 西西人体一区二区| 一本色道久久加勒比88综合| 欧美国产日韩a欧美在线观看|