日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

c++ 内存管理_Python Bindings - 从 Python 调用 C/C++

發(fā)布時間:2024/8/23 c/c++ 70 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++ 内存管理_Python Bindings - 从 Python 调用 C/C++ 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

python 最被人詬病的問題是什么? 慢,這是被人詬病最多的問題,很少人知道具體原因,極少人愿意去深入了解并找到原因,更極少的人愿意付出時間去解決這個問題,很多人都是停留在抱怨吐槽階段,知乎上有幾個問題是跟這個問題相關(guān)的,里面有些答案很專業(yè),很早以前我也去找尋過答案,總結(jié)下來:
1. 動態(tài)特性導(dǎo)致解釋器低效(python是非常動態(tài)的語言,為了支持這些動態(tài)特性,付出的是解釋器的低效)
2. python VM 在 GC 方面的低效
3. 由于 GIL 的存在,無法通過多線程支持多核并行計算
4. 沒有 JIT 和更好的 VM,這是相對其它語言來講,比如:Java
所以也就可以圍繞這幾個方面來找到解決方案提升 python 程序的執(zhí)行速度,還是有些人愿意貢獻自己的時間從這些方面去提升 python 的性能,比如 GIL 的問題,我看到 pycon 2019 這位小伙就分享了他嘗試去解決這個問題。
這篇文章是翻譯自 realpython 上題為 Python Bindings: Calling C or C++ From Python 的文章,怎么繞開 GIL 的限制,怎么避免解釋器的低效,python bindings 是一個方案,也是最常用的方案。

您是要從 Python 使用 C 或 C++ 庫的 Python 開發(fā)人員嗎? 如果是這樣,則 Python bindings 允許您調(diào)用函數(shù)并將數(shù)據(jù)從 Python 傳遞到 C 或 C++,從而使您能夠充分利用這兩種語言的優(yōu)勢。 在本教程中,您會看到一些可用于創(chuàng)建 Python bindings 的工具的概述。

在本教程中,您將了解:

  • 為什么要從 Python 調(diào)用 C 或 C++
  • 如何在 C 和 Python 之間傳遞數(shù)據(jù)
  • 哪些工具和方法可以幫助您創(chuàng)建 Python 綁定

本教程針對中級 Python 開發(fā)人員。 它假定您具有 Python 的基礎(chǔ)知識,并且對 C 或 C++ 中的函數(shù)和數(shù)據(jù)類型有所了解。 點擊鏈接,您可以獲得本教程中將看到的所有示例代碼。

讓我們深入研究 Python bindings!

Python Bindings 概述

在深入研究如何從 Python 調(diào)用 C 之前,最好花點時間了解為什么。 在幾種情況下,創(chuàng)建 Python 綁定來調(diào)用 C 庫是一個好主意:

  • 您已經(jīng)擁有一個大型的,經(jīng)過測試的,穩(wěn)定的,用 C++ 編寫的庫,并且希望在 Python 中加以利用。 這可以是通信庫,也可以是與特定硬件對話的庫。 它的作用并不重要。
  • 您想通過將關(guān)鍵部分轉(zhuǎn)換為 C 來加快 Python 代碼的特定部分的速度。C 不僅執(zhí)行速度更快,而且還允許您在小心的情況下擺脫 GIL 的限制。
  • 您想使用Python測試工具對其系統(tǒng)進行大規(guī)模測試。
  • 以上所有都是學(xué)習(xí)創(chuàng)建 Python 綁定 C 庫接口的重要原因。

    注意:在本教程中,您將創(chuàng)建與 C 和 C++ 的 Python 綁定。 大多數(shù)通用概念都適用于兩種語言,因此除非兩種語言之間有特定區(qū)別,否則將使用 C。 通常,每種工具都支持 C 或 C++,但不能同時支持兩者。

    讓我們開始吧!

    編組數(shù)據(jù)類型(Marshalling Data Types)

    等等! 在開始編寫 Python 綁定之前,請查看 Python 和 C 如何存儲數(shù)據(jù)以及這將導(dǎo)致什么類型的問題。 首先,讓我們定義編組(marshalling)。 Wikipedia 對此概念的定義如下:

    將對象的內(nèi)存表示形式轉(zhuǎn)換為適合存儲或傳輸?shù)臄?shù)據(jù)格式的過程。原始鏈接

    出于您的目的,編組是 Python 綁定在準(zhǔn)備將數(shù)據(jù)從 Python 移至 C 或反之時所做的工作。 Python 綁定需要進行編組,因為 Python 和 C 以不同的方式存儲數(shù)據(jù)。 C 以盡可能緊湊的形式將數(shù)據(jù)存儲在內(nèi)存中。 如果使用 uint8_t,則它總共僅使用 8 bits 內(nèi)存。

    另一方面,在 Python 中,一切都是對象。 這意味著每個整數(shù)都會在內(nèi)存中使用很多個字節(jié)。 有多少個取決于您正在運行的 Python 版本,您的操作系統(tǒng)以及其他因素。 這意味著您的 Python 綁定需要為跨邊界傳遞的每個整數(shù)從 C 整數(shù)轉(zhuǎn)換為 Python 整數(shù)。

    其他數(shù)據(jù)類型在兩種語言之間具有相似的關(guān)系。 讓我們依次來看一下:

    • 整數(shù)存儲計數(shù)數(shù)字。 Python 以任意精度存儲整數(shù),這意味著您可以存儲非常非常大的數(shù)字。 C 指定整數(shù)的具體大小。 在語言之間切換時,您需要注意數(shù)據(jù)大小,以防止 Python 整數(shù)值溢出 C 整數(shù)變量。
    • 浮點數(shù)是帶小數(shù)位的數(shù)字。 Python 可以存儲比 C 大得多(小得多)的浮點數(shù)。這意味著您還必須注意這些值以確保它們在范圍內(nèi)。
    • 復(fù)數(shù)是具有虛部的數(shù)字。 盡管 Python 具有內(nèi)置的復(fù)數(shù),而 C 具有復(fù)雜的數(shù),但沒有內(nèi)置的方法可在它們之間進行編組。 要編列復(fù)數(shù),您需要在 C 代碼中構(gòu)建一個結(jié)構(gòu)或類來對其進行管理。
    • 字符串是字符序列。 對于這種常見的數(shù)據(jù)類型,在創(chuàng)建 Python 綁定時,字符串會變得非常棘手。 與其他數(shù)據(jù)類型一樣,Python 和 C 以完全不同的格式存儲字符串。 (與其他數(shù)據(jù)類型不同,C 和 C++ 在這方面也有所不同,這很有趣!)您將研究的每個解決方案在處理字符串方面都有略有不同的方法。
    • 布爾變量只能有兩個值。由于它們在 C 語言中得到支持,因此將它們編組將非常簡單。

    除了數(shù)據(jù)類型轉(zhuǎn)換外,在構(gòu)建 Python 綁定時還需要考慮其他問題。讓我們繼續(xù)探索它們。

    了解可變值和不可變值

    除了所有這些數(shù)據(jù)類型之外,您還必須了解 Python 對象可以是可變和不可變的。 在談?wù)撝祩鬟f或引用傳遞時,C 具有與函數(shù)參數(shù)類似的概念。 在 C 語言中,所有參數(shù)都是傳遞值。 如果要允許函數(shù)在調(diào)用方中更改變量,則需要將指針傳遞給該變量。

    您可能想知道是否可以通過使用指針簡單地將不可變對象傳遞給 C 來解決不可變限制。 除非您進入丑陋且不可攜帶的極端,否則 Python 不會為您提供指向?qū)ο蟮闹羔?#xff0c;因此這是行不通的。 如果您要在 C 語言中修改 Python 對象,則需要采取額外的步驟來實現(xiàn)。 這些步驟將取決于您使用的工具,你后面會看到。

    因此,您可以在項目清單中添加不變性,以便在創(chuàng)建 Python 綁定時考慮。創(chuàng)建此清單的最后一步是如何處理 Python 和 C 處理內(nèi)存管理的不同方式。

    管理內(nèi)存

    C 和 Python 對內(nèi)存的管理方式不同。 在 C 語言中,開發(fā)人員必須管理所有內(nèi)存分配,并確保一次只能釋放一次。 Python 使用垃圾收集器為您解決此問題。

    盡管每種方法都有其優(yōu)勢,但在創(chuàng)建 Python 綁定時確實增加了額外的麻煩。 您需要了解每個對象的內(nèi)存分配位置,并確保僅在語言屏障的同一側(cè)釋放內(nèi)存。

    例如,當(dāng)您設(shè)置x = 3時,將創(chuàng)建一個 Python 對象。該對象的內(nèi)存在 Python 端分配,需要進行垃圾回收。 幸運的是,使用 Python 對象,很難做其他任何事情。 看一下 C 語言中的相反情況,您可以在其中直接分配一個內(nèi)存塊:

    int* iPtr = (int*)malloc(sizeof(int));

    執(zhí)行此操作時,需要確保在 C 中釋放此指針。這可能意味著需要手動將代碼添加到 Python 綁定中。

    這樣就完善了您的常規(guī)主題清單。 讓我們開始設(shè)置你的系統(tǒng),以便您編寫一些代碼!

    設(shè)置環(huán)境

    在本教程中,您將使用 Real Python GitHub repo 中已經(jīng)存在的 C 和 C++ 庫來演示每個工具的測試。 目的是您可以將這些構(gòu)想用于任何 C 庫。 要遵循此處的所有示例,您需要具備以下條件:

    • 已安裝 C++ 庫并了解命令行調(diào)用的路徑
    • Python 開發(fā)工具:
      • 對于Linux,這是 python3-dev 或 python3-devel 軟件包,具體取決于您的發(fā)行版。
      • 對于Windows,有多個選項。
    • Python 3.6或更高版本
    • 一個虛擬環(huán)境(推薦,但不是必需的)
    • invoke 工具

    最后一個可能對您來說是新手,所以讓我們仔細看看。

    使用 invoke 工具

    invoke是本教程中用于構(gòu)建和測試 Python 綁定的工具。 它具有類似的用途,但使用 Python 而不是 Makefiles。 您需要使用 pip 在虛擬環(huán)境中安裝 invoke:

    $ python3 -m pip install invoke

    要運行它,請鍵入 invoke,然后鍵入要執(zhí)行的任務(wù):

    $ invoke build-cmult ================================================== = Building C Library * Complete

    要查看可用的任務(wù),請使用 --list 選項:

    $ invoke --list Available tasks:all Build and run all testsbuild-cffi Build the CFFI Python bindingsbuild-cmult Build the shared library for the sample C codebuild-cppmult Build the shared library for the sample C++ codebuild-cython Build the cython extension modulebuild-pybind11 Build the pybind11 wrapper libraryclean Remove any built objectstest-cffi Run the script to test CFFItest-ctypes Run the script to test ctypestest-cython Run the script to test Cythontest-pybind11 Run the script to test PyBind11

    請注意,當(dāng)您查看定義了調(diào)用任務(wù)的 task.py 文件時,您會看到列出的第二個任務(wù)的名稱為 build_cffi。 但是,--list的輸出將其顯示為 build-cffi。 減號(-)不能用作 Python 名稱的一部分,因此該文件改用下劃線(_)。

    對于您要檢查的每種工具,都會定義一個構(gòu)建和測試任務(wù)。 例如,要運行 CFFI 的代碼,可以鍵入 invoke build-cffi test-cffi。 ctypes 是一個例外,因為 ctypes 沒有構(gòu)建階段。 此外,為方便起見還添加了兩個特殊任務(wù):

    • invoke all 運行所有工具的構(gòu)建和測試任務(wù)。
    • invoke clean 刪除所有生成的文件。

    現(xiàn)在,您已經(jīng)了解了如何運行代碼,讓我們先看一下要包裝的 C 代碼,然后再訪問工具概述。

    C 或 C++ 源代碼

    在下面的每個示例部分中,您將為 C 或 C++ 中的同一函數(shù)創(chuàng)建 Python 綁定。 這些部分旨在讓您了解每種方法的外觀,而不是該工具的深入教程,因此您要包裝的功能很小。 您將為其創(chuàng)建 Python 綁定的函數(shù)將一個整數(shù)和一個浮點數(shù)作為輸入?yún)?shù),并返回一個浮點數(shù),該浮點數(shù)是兩個數(shù)字的乘積:

    // cmult.c float cmult(int int_param, float float_param) {float return_value = int_param * float_param;printf(" In cmult : int: %d float %.1f returning %.1fn", int_param,float_param, return_value);return return_value; }

    C 和 C++ 函數(shù)幾乎完全相同,它們之間的名稱和字符串有所不同。 您可以通過單擊鏈接獲得所有代碼的副本:

    現(xiàn)在,您已經(jīng)克隆了庫并安裝了工具,您可以構(gòu)建和測試工具。因此,讓我們深入了解下面的每個部分!

    ctypes

    您將從 ctypes 開始,這是標(biāo)準(zhǔn)庫中用于創(chuàng)建 Python 綁定的工具。 它提供了一個低級工具集,用于在 Python 和 C 之間加載共享庫并編組數(shù)據(jù)。

    如何安裝

    ctypes 的一大優(yōu)點是它是 Python 標(biāo)準(zhǔn)庫的一部分。 它是在 Python 2.5 版中添加的,因此你很可能已經(jīng)有了。 您可以像使用 sys 或 time 模塊一樣導(dǎo)入它。

    調(diào)用方法

    加載 C 庫并調(diào)用該函數(shù)的所有代碼都在您的 Python 程序中。 很好,因為您的過程沒有多余的步驟。 您只需運行您的程序,一切都將得到照顧。 要在 ctypes 中創(chuàng)建 Python 綁定,您需要執(zhí)行以下步驟:

  • 加載庫。
  • 包裝一些輸入?yún)?shù)。
  • 告訴 ctypes 函數(shù)的返回類型。
  • 您將依次查看每一個。

    加載庫

    ctypes 提供了幾種加載共享庫的方法,其中一些是特定于平臺的。 以您的示例為例,您將直接通過完整路徑傳遞所需的共享庫來創(chuàng)建 ctypes.CDLL 對象:

    # ctypes_test.py import ctypes import pathlibif __name__ == "__main__":# Load the shared library into ctypeslibname = pathlib.Path().absolute() / "libcmult.so"c_lib = ctypes.CDLL(libname)

    這適用于共享庫與 Python 腳本位于同一目錄中的情況,但是當(dāng)您嘗試從 Python 綁定以外的包中加載庫時要小心。 在 ctypes 文檔中有許多有關(guān)平臺和特定情況的加載庫和查找路徑的詳細信息。

    注意:庫加載期間可能會出現(xiàn)許多特定于平臺的問題。實例生效后,最好進行增量更改。

    現(xiàn)在您已將庫加載到 Python 中,可以嘗試調(diào)用它了!

    調(diào)用你編寫的方法

    請記住,您的C函數(shù)的函數(shù)原型如下:

    // cmult.h float cmult(int int_param, float float_param);

    您需要傳入一個整數(shù)和一個浮點數(shù),并且可以期望返回一個浮點數(shù)。 整數(shù)和浮點數(shù)在 Python 和 C 中都具有原生支持,因此您希望這種情況適用于合理的值。

    將庫加載到 Python 綁定中后,該函數(shù)將成為 c_lib 的屬性,c_lib 是您之前創(chuàng)建的 CDLL 對象。 您可以嘗試這樣稱呼它:

    x, y = 6, 2.3 answer = c_lib.cmult(x, y)

    糟糕!這行不通。在示例 repo 中,此行已被注釋掉,因為它失敗了。如果您嘗試通過該調(diào)用運行,則 Python 會報錯:

    $ invoke test-ctypes Traceback (most recent call last):File "ctypes_test.py", line 16, in <module>answer = c_lib.cmult(x, y) ctypes.ArgumentError: argument 2: <class 'TypeError'>: Don't know how to convert parameter 2

    看來您需要告訴 ctypes 任何不是整數(shù)的參數(shù)。 除非您明確告訴 ctypes,否則 ctypes 對該函數(shù)一無所知。 除非另有說明,否則任何參數(shù)均假定為整數(shù)。 ctypes 不知道如何將 y 中存儲的值 2.3 轉(zhuǎn)換為整數(shù),因此失敗。

    要解決此問題,您需要根據(jù)數(shù)字創(chuàng)建一個 c_float。您可以在調(diào)用該函數(shù)的行中執(zhí)行以下操作:

    # ctypes_test.py answer = c_lib.cmult(x, ctypes.c_float(y)) print(f" In Python: int: {x} float {y:.1f} return val {answer:.1f}")

    現(xiàn)在,當(dāng)您運行此代碼時,它將返回您傳入的兩個數(shù)字的乘積:

    $ invoke test-ctypesIn cmult : int: 6 float 2.3 returning 13.8In Python: int: 6 float 2.3 return val 48.0

    請稍等... 6 乘以 2.3 不是 48.0!

    事實證明,與輸入?yún)?shù)一樣,ctypes 假定您的函數(shù)返回一個 int 值。 實際上,您的函數(shù)返回一個浮點數(shù),該浮點數(shù)被錯誤地編組。 就像輸入?yún)?shù)一樣,您需要告訴 ctypes 使用其他類型。 這里的語法略有不同:

    # ctypes_test.py c_lib.cmult.restype = ctypes.c_float answer = c_lib.cmult(x, ctypes.c_float(y)) print(f" In Python: int: {x} float {y:.1f} return val {answer:.1f}")

    這應(yīng)該夠了吧。 讓我們運行整個 test-ctypes 目標(biāo),看看有什么。 請記住,輸出的第一部分是在將函數(shù)的 restype 固定為 float 之前:

    $ invoke test-ctypes ================================================== = Building C Library * Complete ================================================== = Testing ctypes ModuleIn cmult : int: 6 float 2.3 returning 13.8In Python: int: 6 float 2.3 return val 48.0In cmult : int: 6 float 2.3 returning 13.8In Python: int: 6 float 2.3 return val 13.8

    這樣更好! 當(dāng)?shù)谝粋€未經(jīng)更正的版本返回錯誤值時,您的固定版本同意 C 函數(shù)。 C 和 Python 都得到相同的結(jié)果! 現(xiàn)在它可以正常工作了,看看為什么您可能不希望使用 ctypes。

    長處和短處

    與其他工具相比,ctypes 的最大優(yōu)點是它內(nèi)置在標(biāo)準(zhǔn)庫中。它也不需要任何額外的步驟,因為所有工作都是在 Python 程序中完成的。

    此外,所使用的概念是低級的,這使您剛進行的練習(xí)變得易于管理。 但是,由于缺乏自動化,更復(fù)雜的任務(wù)變得繁瑣。 在下一節(jié)中,您將看到一個為流程增加一些自動化的工具。

    CFFI

    CFFI 是 Python 的 C 外部函數(shù)接口。 它采用一種更加自動化的方法來生成 Python 綁定。 CFFI 有多種構(gòu)建和使用 Python 綁定的方式。 有兩個不同的選項可供選擇,這為您提供了四種可能的模式:

    • ABI vs API: API 模式使用 C 編譯器生成完整的 Python 模塊,而 ABI 模式加載共享庫并直接與其交互。 如果不運行編譯器,則正確構(gòu)造結(jié)構(gòu)和參數(shù)很容易出錯。 文檔強烈建議使用 API 模式。
    • in-line vs out-of-line: 這兩種模式之間的區(qū)別在于速度和便利性之間的權(quán)衡:
      • In-line mode 在每次腳本運行時,都會編譯 Python 綁定。這很方便,因為您不需要額外的構(gòu)建步驟。但是,它的確會使您的程序變慢。
      • Out-of-line mode 需要一個額外的步驟來一次生成 Python 綁定,然后在每次運行程序時都使用它們。這要快得多,但是對于您的應(yīng)用程序可能并不重要。

    在此示例中,您將使用 API?? out-of-line mode,該模式會生成最快的代碼,并且通常看起來與您將在本教程后面創(chuàng)建的其他 Python 綁定類似。

    如何安裝

    由于 CFFI 不是標(biāo)準(zhǔn)庫的一部分,因此您需要將其安裝在計算機上。 建議您為此創(chuàng)建一個虛擬環(huán)境。 幸運的是,CFFI 使用 pip 進行安裝:

    $ python3 -m pip install cffi

    這會將軟件包安裝到您的虛擬環(huán)境中。如果您已經(jīng)從 requirements.txt 安裝了該文件,則應(yīng)注意這一點。您可以通過訪問鏈接中的 repo 來查看requirements.txt:

    現(xiàn)在,您已經(jīng)安裝了 CFFI,現(xiàn)在該試一下了!

    調(diào)用方法

    與 ctypes 不同,使用 CFFI,您可以創(chuàng)建完整的 Python 模塊。 您可以像導(dǎo)入標(biāo)準(zhǔn)庫中的任何其他模塊一樣導(dǎo)入該模塊。 您需要做一些額外的工作來構(gòu)建 Python 模塊。 要使用 CFFI Python 綁定,您需要執(zhí)行以下步驟:

    • 編寫一些描述綁定的 Python 代碼。
    • 運行該代碼以生成可加載模塊。
    • 修改調(diào)用代碼以導(dǎo)入和使用新創(chuàng)建的模塊。

    這似乎是一項艱巨的工作,但您將逐步完成這些步驟,并了解其工作原理。

    編寫綁定

    CFFI 提供了一些方法,可以在生成 Python 綁定時讀取 C 頭文件來完成大部分工作。 在 CFFI 文檔中,執(zhí)行此操作的代碼放置在單獨的 Python 文件中。 在此示例中,您會將代碼直接放入使用 Python 文件作為輸入的構(gòu)建工具調(diào)用中。 要使用 CFFI,首先創(chuàng)建一個 cffi.FFI 對象,該對象提供了所需的三種方法:

    # tasks.py import cffi ... """ Build the CFFI Python bindings """ print_banner("Building CFFI Module") ffi = cffi.FFI()

    獲得FFI后,您將使用 .cdef() 自動處理頭文件的內(nèi)容。這將為您創(chuàng)建包裝器方法,用來編組來自 Python 的數(shù)據(jù):

    # tasks.py this_dir = pathlib.Path().absolute() h_file_name = this_dir / "cmult.h" with open(h_file_name) as h_file:ffi.cdef(h_file.read())

    讀取和處理頭文件是第一步。之后,您需要使用 .set_source() 來描述 CFFI 將生成的源文件:

    # tasks.py ffi.set_source("cffi_example",# Since you're calling a fully-built library directly, no custom source# is necessary. You need to include the .h files, though, because behind# the scenes cffi generates a .c file that contains a Python-friendly# wrapper around each of the functions.'#include "cmult.h"',# The important thing is to include the pre-built lib in the list of# libraries you're linking against:libraries=["cmult"],library_dirs=[this_dir.as_posix()],extra_link_args=["-Wl,-rpath,."], )

    以下是您要傳遞的參數(shù)的明細:

    • cffi_example 是將在文件系統(tǒng)上創(chuàng)建的源文件的基本名稱。 CFFI 將生成一個 .c 文件,將其編譯為 .o 文件,并將其鏈接至 .so 或 .dll 文件。
    • #include "cmult.h" 是自定義 C 源代碼,在編譯之前將包含在生成的源代碼中。在這里,您僅包含要為其生成綁定的 .h 文件,但這可用于一些有趣的自定義。
    • library = ["cmult"] 告訴鏈接器您先前存在的 C 庫的名稱。這是一個列表,因此您可以根據(jù)需要指定幾個庫。
    • library_dirs = [this_dir.as_posix(),] 是目錄列表,它告訴鏈接程序在何處查找上述庫列表。
    • extra_link_args = ['-Wl,-rpath,.'] 是一組選項,它們生成一個共享庫,該共享庫將在當(dāng)前路徑(.)中查找需要加載的其他庫。

    構(gòu)建 Python 綁定

    調(diào)用 .set_source() 不會建立 Python 綁定。它僅設(shè)置元數(shù)據(jù)來描述將要生成的內(nèi)容。要構(gòu)建 Python 綁定,您需要調(diào)用 .compile():

    # tasks.py ffi.compile()

    這通過生成 .c 文件,.o 文件和共享庫來完成。您剛瀏覽過的 invoke 任務(wù)可以在命令行上運行以構(gòu)建 Python 綁定:

    $ invoke build-cffi ================================================== = Building C Library * Complete ================================================== = Building CFFI Module * Complete

    您已經(jīng)有了 CFFI Python 綁定,因此現(xiàn)在該運行該代碼了!

    調(diào)用你編寫的方法

    在完成所有工作之后,您配置并運行了 CFFI 編譯器,使用生成的 Python 綁定看起來就像使用任何其他 Python 模塊一樣:

    # cffi_test.py import cffi_exampleif __name__ == "__main__":# Sample data for your callx, y = 6, 2.3answer = cffi_example.lib.cmult(x, y)print(f" In Python: int: {x} float {y:.1f} return val {answer:.1f}")

    導(dǎo)入新模塊,然后可以直接調(diào)用 cmult()。要測試它,請使用 test-cffi 任務(wù):

    $ invoke test-cffi ================================================== = Testing CFFI ModuleIn cmult : int: 6 float 2.3 returning 13.8In Python: int: 6 float 2.3 return val 13.8

    這將運行 cffi_test.py 程序,該程序?qū)y試您使用 CFFI 創(chuàng)建的新 Python 綁定。這樣就完成了有關(guān)編寫和使用 CFFI Python 綁定的部分。

    長處和短處

    似乎 ctypes 比您剛剛看到的 CFFI 示例所需的工作更少。盡管在這種用例中確實如此,但由于許多功能包裝的自動化,CFFI 可以比 ctypes 更好地擴展到較大的項目。

    CFFI 還產(chǎn)生了完全不同的用戶體驗。 ctypes 允許您將預(yù)先存在的 C 庫直接加載到 Python 程序中。另一方面,CFFI 創(chuàng)建了一個新的 Python 模塊,該模塊可以像其他 Python 模塊一樣加載。

    更重要的是,通過上面使用的 out-of-line API 方法,創(chuàng)建 Python 綁定的時間代價是在構(gòu)建它時就完成一次,而在每次運行代碼時都不會發(fā)生。 對于小型程序,這可能沒什么大不了的,但是 CFFI 也可以通過這種方式更好地擴展到較大的項目。

    與 ctypes 一樣,使用 CFFI 僅允許您直接與 C 庫連接。 C++ 庫需要大量工作才能使用。在下一節(jié)中,您將看到專注于 C++ 的 Python 綁定工具。

    PyBind11

    PyBind11 采用了完全不同的方法來創(chuàng)建 Python 綁定。 除了將重點從 C 轉(zhuǎn)移到 C++ 之外,它還使用 C++ 來指定和構(gòu)建模塊,從而使其能夠利用 C++ 中的元編程工具。 與 CFFI 一樣,從 PyBind11 生成的 Python 綁定是一個完整的 Python 模塊,可以直接導(dǎo)入和使用。

    PyBind11 是在 Boost::Python 庫之后建模的,并具有類似的接口。 它將它的使用限制在 C++11 和更高版本中,但是,與支持所有功能的 Boost 相比,它可以簡化并加快處理速度。

    如何安裝

    PyBind11 文檔的第一步部分將引導(dǎo)您逐步了解如何下載和構(gòu)建 PyBind11 的測試用例。 盡管似乎并非嚴(yán)格要求這樣做,但按照以下步驟進行操作可以確保您設(shè)置正確的 C++ 和 Python 工具。

    注意:PyBind11的大多數(shù)示例都使用 cmake,這是構(gòu)建 C 和 C++ 項目的好工具。 但是,對于此演示,您將繼續(xù)使用調(diào)用工具,該工具將遵循文檔的手動構(gòu)建部分中的說明。

    您需要將此工具安裝到虛擬環(huán)境中:

    $ python3 -m pip install pybind11

    PyBind11 是一個全標(biāo)題庫,與 Boost 的大部分相似。 這允許 pip 將庫的實際 C++ 源直接安裝到您的虛擬環(huán)境中。

    調(diào)用方法

    在深入研究之前,請注意,您使用的是其他 C++ 源文件 cppmult.cpp,而不是先前示例中使用的 C 文件。 兩種語言的功能基本相同。

    編寫綁定

    與 CFFI 相似,您需要創(chuàng)建一些代碼來告訴該工具如何構(gòu)建 Python 綁定。 與 CFFI 不同,此代碼將使用 C++ 而不是 Python。 幸運的是,所需代碼最少:

    // pybind11_wrapper.cpp #include <pybind11/pybind11.h> #include <cppmult.hpp>PYBIND11_MODULE(pybind11_example, m) {m.doc() = "pybind11 example plugin"; // Optional module docstringm.def("cpp_function", &cppmult, "A function that multiplies two numbers"); }

    由于 PyBind11 將大量信息打包到幾行中,因此讓我們一次來看一下。

    前兩行包括 pybind11.h 文件和 C++ 庫 cppmult.hpp 的頭文件。之后,您將擁有 PYBIND11_MODULE 宏。這擴展為 PyBind11 源代碼中很好描述的 C++ 代碼塊:

    這個宏創(chuàng)建入口點,當(dāng) Python 解釋器導(dǎo)入擴展模塊時,該入口點將被調(diào)用。 模塊名稱作為第一個參數(shù)給出,不應(yīng)使用引號引起來。 第二個宏參數(shù)定義了 py::module 類型的變量,可用于初始化模塊。原始鏈接

    對您而言,這意味著在本示例中,您正在創(chuàng)建一個名為 pybind11_example 的模塊,其余代碼將使用 m 作為 py::module 對象的名稱。 在下一行中,在您定義的 C++ 函數(shù)中,為模塊創(chuàng)建一個文檔字符串。 雖然這是可選的,但可以使您的模塊更加 Pythonic。

    最后,您有 m.def() 調(diào)用。 這將定義由您的新 Python 綁定導(dǎo)出的函數(shù),這意味著它將在 Python 中可見。 在此示例中,您傳遞了三個參數(shù):

    • cpp_function 是您將在 Python 中使用的函數(shù)的導(dǎo)出名稱。 如本例所示,它不需要匹配 C++ 函數(shù)的名稱。
    • &cppmult 使用要導(dǎo)出的函數(shù)的地址。
    • "A function..." 是該函數(shù)的可選文檔字符串。

    既然您已經(jīng)有了 Python 綁定的代碼,請看一下如何將其構(gòu)建到 Python 模塊中。

    構(gòu)建 python 綁定

    在 PyBind11 中用于構(gòu)建 Python 綁定的工具是 C++ 編譯器本身。您可能需要修改編譯器和操作系統(tǒng)的默認設(shè)置。

    首先,您必須構(gòu)建要為其創(chuàng)建綁定的 C++ 庫。 例如,您可以將 cppmult 庫直接構(gòu)建到 Python 綁定庫中。 但是,對于大多數(shù)實際示例,您將擁有一個要包裝的預(yù)先存在的庫,因此您將單獨構(gòu)建 cppmult 庫。 該構(gòu)建是對編譯器的一個標(biāo)準(zhǔn)調(diào)用,以構(gòu)建一個共享庫:

    # tasks.py invoke.run("g++ -O3 -Wall -Werror -shared -std=c++11 -fPIC cppmult.cpp ""-o libcppmult.so " )

    使用 invoke build-cppmult 運行它會生成 libcppmult.so:

    $ invoke build-cppmult ================================================== = Building C++ Library * Complete

    另一方面,Python 綁定的構(gòu)建需要一些特殊的細節(jié):

    # tasks.py invoke.run("g++ -O3 -Wall -Werror -shared -std=c++11 -fPIC ""`python3 -m pybind11 --includes` ""-I /usr/include/python3.7 -I . ""{0} ""-o {1}`python3.7-config --extension-suffix` ""-L. -lcppmult -Wl,-rpath,.".format(cpp_name, extension_name) )

    讓我們逐行瀏覽。 第 3 行包含相當(dāng)標(biāo)準(zhǔn)的 C++ 編譯器標(biāo)志,這些標(biāo)志指示一些詳細信息,包括您希望捕獲所有警告并將其視為錯誤,需要共享庫以及正在使用 C++11。

    第 4 行是魔術(shù)的第一步。它調(diào)用 pybind11 模塊,使其為 PyBind11 生成正確的包含路徑。您可以直接在控制臺上運行此命令以查看其作用:

    $ python3 -m pybind11 --includes -I/home/jima/.virtualenvs/realpython/include/python3.7m -I/home/jima/.virtualenvs/realpython/include/site/python3.7

    您的輸出應(yīng)該相似,但顯示不同的路徑。

    在編譯調(diào)用的第 5 行中,您可以看到您還在將路徑添加到 Python 開發(fā)人員包含的文件中。 建議您不要鏈接到 Python 庫本身,但是源代碼需要 Python.h 中的一些代碼才能發(fā)揮其魔力。 幸運的是,它使用的代碼在 Python 版本之間相當(dāng)穩(wěn)定。

    第5行還使用 -I. 將當(dāng)前目錄添加到包含路徑列表中。這樣可以解析包裝代碼中的 #include <cppmult.hpp>行。

    第 6 行指定源文件的名稱,即 pybind11_wrapper.cpp。 然后,在第 7 行上,您將看到更多的構(gòu)建魔術(shù)正在發(fā)生。 此行指定輸出文件的名稱。 Python 在模塊命名方面有一些特別的想法,包括 Python 版本,機器架構(gòu)和其他細節(jié)。 Python 還提供了一個工具來幫助解決這個問題,稱為 python3.7-config:

    $ python3.7-config --extension-suffix .cpython-37m-x86_64-linux-gnu.so

    如果您使用的是其他版本的 Python,則可能需要修改命令。 如果您使用其他版本的 Python 或使用其他操作系統(tǒng),則結(jié)果可能會發(fā)生變化。

    構(gòu)建命令的最后一行(第 8 行)將鏈接器指向您之前構(gòu)建的 libcppmult 庫。 rpath 部分告訴鏈接器將信息添加到共享庫,以幫助操作系統(tǒng)在運行時找到 libcppmult。 最后,您會注意到該字符串的格式為 cpp_name 和 extension_name。 在下一部分中使用 Cython 構(gòu)建 Python 綁定模塊時,將再次使用此功能。

    $ invoke build-pybind11 ================================================== = Building C++ Library * Complete ================================================== = Building PyBind11 Module * Complete

    是的!您已經(jīng)使用 PyBind11 構(gòu)建了 Python 綁定。現(xiàn)在該進行測試了!

    調(diào)用你編寫的方法

    與上面的 CFFI 示例類似,完成創(chuàng)建 Python 綁定的繁重工作后,調(diào)用函數(shù)看起來就像普通的 Python 代碼:

    # pybind11_test.py import pybind11_exampleif __name__ == "__main__":# Sample data for your callx, y = 6, 2.3answer = pybind11_example.cpp_function(x, y)print(f" In Python: int: {x} float {y:.1f} return val {answer:.1f}")

    由于您在 PYBIND11_MODULE 宏中使用了 pybind11_example 作為模塊的名稱,因此,這就是您導(dǎo)入的名稱。 在 m.def() 調(diào)用中,您告訴 PyBind11 將 cppmult 函數(shù)導(dǎo)出為 cpp_function,這就是從 Python 調(diào)用它的方法。

    您也可以使用 invoke 對其進行測試:

    $ invoke test-pybind11 ================================================== = Testing PyBind11 ModuleIn cppmul: int: 6 float 2.3 returning 13.8In Python: int: 6 float 2.3 return val 13.8

    這就是 PyBind11 的樣子。接下來,您將了解何時以及為什么 PyBind11 是適合該工作的工具。

    長處和短處

    PyBind11 專注于 C++ 而不是 C,這使其不同于 ctypes 和 CFFI。它具有一些功能,使其對于 C++ 庫非常有吸引力:

    • 它支持類。
    • 它處理多態(tài)子類化。
    • 它使您可以從 Python 和許多其他工具向?qū)ο筇砑觿討B(tài)屬性,而這對于您已經(jīng)研究過的基于 C 的工具來說是很難做到的。

    話雖這么說,您需要做一些設(shè)置和配置來啟動和運行 PyBind11。 正確安裝和構(gòu)建可能有些棘手,但是一旦完成,它似乎就很牢固了。 另外,PyBind11 要求您至少使用 C++11 或更高版本。 對于大多數(shù)項目而言,這不太可能成為一個很大的限制,但您可能需要考慮。

    最后,創(chuàng)建 Python 綁定所需編寫的額外代碼是 C++,而不是 Python。 這可能對您來說不是問題,但與您在此處看到的跟其他工具不同。 在下一節(jié)中,您將繼續(xù)學(xué)習(xí) Cython,它采用了完全不同的方法來解決此問題。

    Cython

    Cython 用于創(chuàng)建 Python 綁定的方法,使用類似于 Python 的語言來定義綁定,然后生成可編譯到模塊中的 C 或 C++ 代碼。 有多種使用 Cython 構(gòu)建 Python 綁定的方法。 最常見的一種是使用 distutils 中的安裝程序。 在此示例中,您將繼續(xù)使用 invoke 工具,該工具將使您能夠精確執(zhí)行所運行的命令。

    如何安裝

    Cython 是一個 Python 模塊,可以從 PyPI 安裝到您的虛擬環(huán)境中:

    $ python3 -m pip install cython

    同樣,如果您已經(jīng)將 requirements.txt 文件安裝到虛擬環(huán)境中,則該文件已經(jīng)存在。您可以通過單擊鏈接來獲取requirements.txt 的副本。

    那應(yīng)該已經(jīng)準(zhǔn)備好與 Cython 合作!

    調(diào)用方法

    要使用 Cython 構(gòu)建 Python 綁定,您將遵循與用于 CFFI 和 PyBind11 的步驟相似的步驟。 您將編寫綁定,構(gòu)建它們,然后運行 Python 代碼來調(diào)用它們。 Cython 可以同時支持 C 和 C++。 在此示例中,您將使用在上面的 PyBind11 示例中使用的 cppmult 庫。

    編寫綁定

    在 Cython 中聲明模塊的最常見形式是使用 .pyx 文件:

    # cython_example.pyx """ Example cython interface definition """cdef extern from "cppmult.hpp":float cppmult(int int_param, float float_param)def pymult( int_param, float_param ):return cppmult( int_param, float_param )

    這里有兩個部分:

    • 第 3 行和第 4 行告訴 Cython 您正在使用 cppmult.hpp 中的 cppmult()。
    • 第 6 行和第 7 行創(chuàng)建了包裝函數(shù) pymult(),以調(diào)用 cppmult()。

    這里使用的語言是 C,C++ 和 Python 的特殊組合。 不過,對于 Python 開發(fā)人員來說,它看起來相當(dāng)熟悉,因為其目標(biāo)是使過程變得更容易。

    使用 cdef extern... 的第一部分告訴 Cython,以下函數(shù)聲明也在 cppmult.hpp 文件中找到。 這對于確保針對與 C++ 代碼相同的聲明構(gòu)建 Python 綁定很有用。 第二部分看起來像是常規(guī)的 Python 函數(shù)-因為它是! 本部分創(chuàng)建可訪問 C++ 函數(shù) cppmult 的 Python 函數(shù)。

    現(xiàn)在您已經(jīng)定義了 Python 綁定,是時候構(gòu)建它們了!

    構(gòu)建 python 綁定

    Cython 的構(gòu)建過程與您用于 PyBind11 的過程相似。您首先在 .pyx 文件上運行 Cython 以生成一個 .cpp 文件。完成此操作后,可以使用與 PyBind11 相同的功能對其進行編譯:

    # tasks.py def compile_python_module(cpp_name, extension_name):invoke.run("g++ -O3 -Wall -Werror -shared -std=c++11 -fPIC ""`python3 -m pybind11 --includes` ""-I /usr/include/python3.7 -I . ""{0} ""-o {1}`python3.7-config --extension-suffix` ""-L. -lcppmult -Wl,-rpath,.".format(cpp_name, extension_name))def build_cython(c):""" Build the cython extension module """print_banner("Building Cython Module")# Run cython on the pyx file to create a .cpp fileinvoke.run("cython --cplus -3 cython_example.pyx -o cython_wrapper.cpp")# Compile and link the cython wrapper librarycompile_python_module("cython_wrapper.cpp", "cython_example")print("* Complete")

    首先在 .pyx 文件上運行 cython。您可以在此命令上使用一些選項:

    • --cplus告訴編譯器生成 C++ 文件而不是 C 文件。
    • -3 切換 Cython 生成 Python 3 語法,而不是 Python 2。
    • -o cython_wrapper.cpp 指定要生成的文件的名稱。

    生成 C++ 文件后,就像使用 PyBind11 一樣,您可以使用 C++ 編譯器生成 Python 綁定。 請注意,使用 pybind11 工具生成額外包含路徑的調(diào)用仍在該函數(shù)中。 在這里不會造成任何傷害,因為您的源碼將不需要這些。

    在 invoke 中運行此任務(wù)將產(chǎn)生以下輸出:

    $ invoke build-cython ================================================== = Building C++ Library * Complete ================================================== = Building Cython Module * Complete

    您會看到它構(gòu)建了 cppmult 庫,然后構(gòu)建了 cython 模塊來包裝它。現(xiàn)在您有了 Cython Python 綁定。(嘗試快速地說出……),現(xiàn)在該進行測試了!

    調(diào)用你編寫的方法

    調(diào)用新的 Python 綁定的 Python 代碼與用于測試其他模塊的代碼非常相似:

    # cython_test.py import cython_example# Sample data for your call x, y = 6, 2.3answer = cython_example.pymult(x, y) print(f" In Python: int: {x} float {y:.1f} return val {answer:.1f}")

    第 2 行將導(dǎo)入新的 Python 綁定模塊,并在第 7 行調(diào)用 pymult()。請記住,.pyx 文件在 cppmult() 周圍提供了 Python 包裝器,并將其重命名為 pymult。使用 invoke 運行測試將產(chǎn)生以下結(jié)果:

    $ invoke test-cython ================================================== = Testing Cython ModuleIn cppmul: int: 6 float 2.3 returning 13.8In Python: int: 6 float 2.3 return val 13.8

    您得到與以前相同的結(jié)果!

    長處和短處

    Cython 是一個相對復(fù)雜的工具,在為 C 或 C++ 創(chuàng)建 Python 綁定時,可以為您提供更深層次的控制。 盡管這里沒有詳細介紹,但它提供了一種 Python 風(fēng)格的方法來編寫可手動控制 GIL 的代碼,從而可以顯著加快某些類型的問題。

    但是,這種 Python 風(fēng)格的語言并不完全是 Python,因此,當(dāng)您逐漸確定 C 和 Python 的哪些部分適合您時,會有一條學(xué)習(xí)曲線。

    其它一些解決方案

    在研究本教程時,我遇到了幾種用于創(chuàng)建 Python 綁定的工具和選項。 盡管我將本概述限制為一些更常見的選項,但我偶然發(fā)現(xiàn)了其他幾種工具。 以下列表并不全面。 如果上述工具之一不適合您的項目,則僅是其他可能性的示例。

    PyBindGen

    PyBindGen 生成用于 C 或 C++ 的 Python 綁定,并用 Python 編寫。 它的目標(biāo)是產(chǎn)生可讀的 C 或 C++ 代碼,這將簡化調(diào)試問題。 目前尚不清楚是否最近更新,因為該文檔將 Python 3.4 列為最新測試版本。 但是,最近幾年每年都有版本發(fā)布。

    Boost.Python

    Boost.Python 具有類似于您在上面看到的 PyBind11 的接口。 這不是巧合,因為 PyBind11 是基于該庫的! Boost.Python 是用完整的 C++ 編寫的,并且在大多數(shù)平臺上支持大多數(shù)(如果不是全部)C++ 版本。 相比之下,PyBind11 僅限于使用現(xiàn)代 C++。

    SIP

    SIP 是為 PyQt 項目開發(fā)的用于生成 Python 綁定的工具集。 wxPython 項目也使用它來生成其綁定。 它具有代碼生成工具和一個額外的 Python 模塊,該模塊為生成的代碼提供支持功能。

    Cppyy

    cppyy 是一個有趣的工具,其設(shè)計目標(biāo)與到目前為止所看到的略有不同。用包作者的話來說:

    “cppyy 的原始想法(可追溯到2001年)是允許生活在 C++ 世界中的 Python 程序員訪問那些 C++ 程序包,而不必直接接觸 C++(或等待 C++ 開發(fā)人員到來并提供綁定)。” 原始鏈接

    Shiboken

    Shiboken 是一種生成 Python 綁定的工具,該工具是為與 Qt 項目關(guān)聯(lián)的 PySide 項目開發(fā)的。 雖然將其設(shè)計為該項目的工具,但文檔顯示它既不是 Qt 也不是 PySide專 用的,并且可以用于其他項目。

    SWIG

    SWIG 是與此處列出的任何其他工具不同的工具。 這是一種通用工具,可用于創(chuàng)建與許多其他語言(不僅限于 Python)的 C 和 C++ 程序的綁定。 在某些項目中,這種為不同語言生成綁定的功能可能會非常有用。 就復(fù)雜性而言,當(dāng)然要付出代價。

    結(jié)論

    恭喜! 現(xiàn)在,您已經(jīng)對用于創(chuàng)建 Python 綁定的幾種不同選項有了一定的概覽。 您已經(jīng)了解了編組數(shù)據(jù)和創(chuàng)建綁定時需要考慮的問題。 您已經(jīng)了解了使用以下工具可以從 Python 調(diào)用 C 或 C++ 函數(shù)的過程:

    • ctypes
    • CFFI
    • PyBind11
    • Cython

    您現(xiàn)在已經(jīng)知道,盡管 ctypes 允許您直接加載 DLL 或共享庫,但其他三個工具需要額外的步驟,但仍會創(chuàng)建完整的 Python 模塊。 另外,您還可以使用 invoke 工具從 Python 側(cè)運行命令行任務(wù)。 單擊鏈接可以獲取在本教程中看到的所有代碼。

    現(xiàn)在選擇您喜歡的工具并開始構(gòu)建這些 Python 綁定吧!特別感謝 Loic Domaigne 對本教程的額外技術(shù)評論。

    總結(jié)

    以上是生活随笔為你收集整理的c++ 内存管理_Python Bindings - 从 Python 调用 C/C++的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    成人动漫视频在线 | 在线a亚洲视频播放在线观看 | .国产精品成人自产拍在线观看6 | 天天操天天摸天天爽 | www.日日操.com| 国产精品一区二区久久精品 | 麻豆传媒视频在线播放 | 午夜免费电影院 | 中文字幕精品一区二区精品 | 偷拍福利视频一区二区三区 | 91黄色免费网站 | 亚洲精品在线国产 | 亚洲砖区区免费 | 国产精品9区 | 久久国产免费看 | 97电影网站| 日本成人中文字幕在线观看 | 成全免费观看视频 | 国产成人高清 | 日韩视频1 | 日韩欧美视频免费在线观看 | 成人国产精品一区 | 欧美少妇的秘密 | 在线免费观看的av网站 | 97精品国产97久久久久久 | 久久久久国产精品午夜一区 | 在线观看www91 | 日日精品| 天堂av在线免费 | 午夜精品电影一区二区在线 | 夜色资源站wwwcom | 精品亚洲一区二区 | 日韩中文字幕免费电影 | 麻豆成人在线观看 | 国产成人精品久久久 | 免费a一级| 国产123区在线观看 国产精品麻豆91 | 免费观看成人 | 久草精品资源 | 激情综合亚洲 | 日韩精品大片 | 久久精品高清视频 | 91精品国产欧美一区二区 | 日韩av片无码一区二区不卡电影 | 国产专区视频在线 | 亚洲精品久久久久久久不卡四虎 | 日韩久久精品一区二区三区下载 | 欧美日韩视频在线一区 | 一区免费视频 | 精品视频www | 久久久在线观看 | 日韩av免费在线看 | 国产精品s色 | 一本一道久久a久久精品蜜桃 | 91精品久久香蕉国产线看观看 | 狠狠色丁香久久婷婷综合五月 | av一级二级 | 日韩在线网| 五月婷网站 | www.狠狠操.com| 丁香六月激情婷婷 | 字幕网在线观看 | 一本色道久久精品 | 99在线免费视频 | 九九热精品视频在线观看 | 久草在线视频看看 | aaa黄色毛片 | 亚洲视频在线播放 | 日韩一区二区免费视频 | 亚洲激情精品 | 免费观看成人网 | 午夜a区| 日韩欧美国产成人 | 日韩色在线观看 | 91精品专区| 日韩欧三级 | av在线短片 | 欧美一二三区在线播放 | 黄色av成人在线 | 国产精品第一视频 | 色综合天天天天做夜夜夜夜做 | 久艹在线播放 | 欧美a级片免费看 | 97电影网站 | 国产a视频免费观看 | 麻豆视频在线免费看 | 97av视频| 亚洲美女视频在线 | 美女久久网站 | 免费看三级 | 欧美日韩一区二区三区免费视频 | 黄色一集片 | 九色最新网址 | 国产白浆在线观看 | 午夜精品福利一区二区 | 日日插日日干 | 在线观看日本高清mv视频 | 久久公开视频 | 久久久久久久av | 欧美动漫一区二区三区 | 人人玩人人爽 | 一区二区 不卡 | 国产精品久久久久av福利动漫 | 99在线免费视频 | 中文字幕在线观看第三页 | 蜜臀av夜夜澡人人爽人人桃色 | 日韩电影中文字幕在线 | 色网站免费在线观看 | 中文有码在线 | 在线 精品 国产 | 国产精品麻豆视频 | 欧美日韩精品综合 | 天天射综合网视频 | 免费观看黄 | www在线免费观看 | 国产一级免费av | 一区二区视频在线免费观看 | 狠狠色丁香婷婷综合久小说久 | 免费看精品久久片 | 久久网址| 国产二区av | 视频在线观看日韩 | 久久综合久久综合这里只有精品 | 欧美综合干 | 成人在线视频免费看 | 久久不射电影院 | 丁香九月激情 | 青青河边草观看完整版高清 | 成人一区不卡 | 精久久久久 | 天天操天天摸天天干 | 日韩一区二区三区免费视频 | 午夜精品av | 久久久久久久久久久影院 | 国产香蕉久久精品综合网 | 国产精品亚洲片在线播放 | 日韩av在线网站 | 九七人人干 | a黄色一级片 | 久久精品99国产精品亚洲最刺激 | 中文电影网 | 日韩美精品视频 | 亚洲天堂首页 | 五月天精品视频 | 欧美精品久久久久久久久久丰满 | 亚洲精品午夜久久久久久久久久久 | 在线观看亚洲免费视频 | 97视频亚洲| 久久久.com | 黄色影院在线观看 | 在线看片中文字幕 | 六月色婷 | 黄污视频网站大全 | 国产成人一区二区啪在线观看 | 久久刺激视频 | 国产手机精品视频 | 黄色小网站在线观看 | 久久久国产精品亚洲一区 | 久久久久久久久久久福利 | 很黄很黄的网站免费的 | 国产视频日韩视频欧美视频 | 亚洲v精品 | 欧美aaaxxxx做受视频 | 精品国产一区二区三区四区在线观看 | 国产亚洲精品久久久久5区 成人h电影在线观看 | 在线观看中文字幕av | 最新av在线免费观看 | 欧美一区免费观看 | 精品在线视频一区 | 免费看搞黄视频网站 | 久久综合毛片 | 欧美日韩高清不卡 | 日本论理电影 | 亚洲美女精品视频 | 久精品视频在线观看 | 久久亚洲成人网 | 91精品国自产在线 | 久草在线资源观看 | 91在线播放视频 | 99久久精品无免国产免费 | 久免费| 国产精品一区二区三区99 | 久久精品电影网 | a v在线视频 | 91精彩视频在线观看 | 国产精品一区二区62 | 久久精品99精品国产香蕉 | 亚洲日韩中文字幕在线播放 | 精品国产一区二区三区四区在线观看 | 国产精品18久久久久久久久久久久 | 四虎影视国产精品免费久久 | 精品久久久久久久久久久院品网 | 99久e精品热线免费 99国产精品久久久久久久久久 | 91九色网站 | 91网址在线看 | 久久精品看片 | 一级黄色在线免费观看 | 免费看av片网站 | 亚洲在线激情 | 97精品超碰一区二区三区 | 一区二区三区四区在线免费观看 | 在线观看涩涩 | 超碰人人在 | 99视频一区 | 国产中年夫妇高潮精品视频 | 国产伦理久久精品久久久久_ | 亚洲国产成人av网 | 日本久久综合视频 | 国内精品久久久久久久97牛牛 | 精品电影一区二区 | 五月婷婷在线综合 | 久久9999久久| 精品伦理一区二区三区 | 91精品国产92久久久久 | 精品在线视频观看 | 久久精品黄 | 在线日韩三级 | 亚洲视频一级 | 人人藻人人澡人人爽 | 色资源二区在线视频 | 又爽又黄又刺激的视频 | 亚洲精品色婷婷 | 亚洲黄色片 | 99在线精品视频观看 | 人人添人人澡人人澡人人人爽 | 91亚·色 | 在线小视频国产 | 国产品久精国精产拍 | 91女子私密保健养生少妇 | 久久久久久久国产精品视频 | 亚洲三级影院 | 日韩一二区在线观看 | 三级午夜片 | 黄色在线免费观看网址 | 美女视频黄网站 | 亚洲综合最新在线 | 五月婷婷综合激情网 | 在线播放国产精品 | 国产精品视频在线观看 | 国产专区在线视频 | 亚洲传媒在线 | 一区二区三区中文字幕在线 | 黄色毛片网站在线观看 | 91精品国产91久久久久 | 91亚·色| 二区三区在线观看 | 91成人短视频在线观看 | 国产高清一级 | 国产精品2020 | 午夜精品一区二区三区在线 | 欧美日韩视频在线一区 | 91av免费看| 国产一级电影 | 五月开心色 | 久草a在线 | 人人爽人人爽人人爽学生一级 | 日韩免费福利 | 天天综合入口 | 久久综合五月天婷婷伊人 | 久久精品aaa | aav在线 | 玖玖在线播放 | 黄色网www | 天天操天天干天天爱 | 婷婷国产精品 | 久久成人免费 | 97超碰在线久草超碰在线观看 | 国产91在线观 | 亚洲理论影院 | 午夜精品福利影院 | 97视频在线观看成人 | 伊人亚洲综合网 | 最近免费中文字幕mv在线视频3 | 久久久久久久久久久免费视频 | 国产精品毛片久久蜜 | 免费视频国产 | 国产精品99久久久久久久久久久久 | av九九九 | 人人爽人人爽人人爽学生一级 | 欧美日韩一区二区三区不卡 | 欧美一区二区三区四区夜夜大片 | 97夜夜澡人人双人人人喊 | 欧美最猛性xxxx | 婷婷电影在线观看 | 亚洲经典在线 | 国内精品中文字幕 | 日本高清久久久 | 国产亚洲成av片在线观看 | 欧美精品v国产精品v日韩精品 | 91在线在线观看 | 玖玖国产精品视频 | 免费观看mv大片高清 | 欧美一区免费观看 | 色狠狠干 | 午夜精品一区二区三区在线视频 | 亚洲激情视频在线观看 | 超碰免费97 | 午夜18视频在线观看 | 九九色在线 | 有码中文字幕 | 久久国产免费视频 | 四虎国产视频 | 欧美一级性生活片 | 又黄又爽又刺激的视频 | av在线播放快速免费阴 | 国产黄色成人av | 在线观看一区二区视频 | 青草视频网 | 成人av在线看 | 国产成人一区二区三区免费看 | 麻豆精品视频在线观看免费 | 91资源在线播放 | 久久久久中文字幕 | 91av视频免费观看 | 久久久久高清毛片一级 | 日韩三级视频 | 91在线看 | 国产电影一区二区三区四区 | 久久久亚洲网站 | 婷婷国产一区二区三区 | av在线收看 | 免费av小说| 狠狠躁天天躁 | 久久国色夜色精品国产 | 日批视频在线观看免费 | 天天爱天天操天天射 | 久久69av| 欧亚久久| 婷婷深爱 | 亚洲免费小视频 | 久久xxxx | 中文字幕观看av | 天天操比 | 久久香蕉国产 | 欧美成年网站 | 免费h视频 | 中文国产字幕在线观看 | 国内视频在线 | 成人av片免费观看app下载 | 91亚洲在线观看 | 夜夜婷婷 | 亚洲成a人片77777潘金莲 | 在线中文字母电影观看 | 亚洲综合色丁香婷婷六月图片 | 91麻豆精品国产自产在线游戏 | www.av免费观看 | 日韩免费在线观看 | 中文字幕av日韩 | 国产原创av片 | 五月香视频在线观看 | 九九免费观看视频 | 亚洲国产经典视频 | 免费国产在线精品 | 日韩一区正在播放 | 久久精品电影院 | 欧亚久久| 国产短视频在线播放 | 欧美日韩精品国产 | 成人一级视频在线观看 | 亚洲日本欧美在线 | 亚洲精品久久久久999中文字幕 | 超碰97人人干 | 香蕉久草 | 亚洲一区二区精品视频 | 亚洲精品国产精品国自产 | 狠狠色丁香婷婷综合橹88 | 久久极品 | 精品9999| 免费av在线| 欧美成人影音 | 精品国产一区二区三区久久久蜜月 | 欧美日韩国产网站 | 国产精品99久久久久的智能播放 | 成人久久网 | a在线一区| 狠狠干综合 | av一区在线| 久久免费视频在线 | 久久都是精品 | ,午夜性刺激免费看视频 | 国产精品久久久久永久免费 | 综合激情久久 | 日韩午夜三级 | 日日爽天天操 | 国产视频一区二区在线播放 | 综合网伊人 | 在线播放视频一区 | 久久国产精品一区二区 | 日本黄色大片儿 | 国产一区黄色 | 成人av资源在线 | 麻豆视频免费在线观看 | 久久免费看 | 国产成人三级 | 黄色电影网站在线观看 | 日韩av高清 | 中文字幕在线一区观看 | 欧美久久久久久久久中文字幕 | 国内免费久久久久久久久久久 | 久久99精品久久久久婷婷 | 手机成人免费视频 | 婷婷丁香综合 | 日韩激情视频在线观看 | 日韩av在线小说 | 日韩mv欧美mv国产精品 | 91麻豆精品久久久久久 | 狠狠狠狠狠狠干 | 日韩精品在线播放 | 午夜精品区 | 国产精品123 | 日韩中文字幕视频在线观看 | 久久99久久99精品中文字幕 | 久久99精品久久久久久三级 | 视频一区二区精品 | 国产五月 | 成人在线视频在线观看 | 2022中文字幕在线观看 | 中文字幕国产一区 | 国产香蕉视频在线播放 | 69av免费视频| 欧美综合国产 | 日韩三级免费观看 | 一区二区精品在线 | 特级毛片网站 | 国产在线第三页 | 久久欧美精品 | 久久精品a | www欧美xxxx | 808电影免费观看三年 | 日韩精品久久久久久中文字幕8 | 日韩av高潮 | 天天干天天碰 | 日韩在线观看中文 | 欧美精品久久 | 色婷婷精品 | 日本3级在线观看 | 狠狠色丁香婷婷综合橹88 | 欧美在线视频不卡 | 国产亚洲精品久久19p | www.五月婷 | 碰天天操天天 | 日韩欧美高清一区二区 | 色在线免费 | 婷婷综合五月 | 岛国片在线 | 91污污视频在线观看 | 国产午夜精品av一区二区 | 日韩va在线观看 | 日韩精品一区二区免费 | 91精品网站在线观看 | 久久综合狠狠综合久久综合88 | 人人澡澡人人 | 亚洲最大成人网4388xx | 18久久久久久 | 欧美a级免费视频 | 国产精品久久久久久妇 | 中文字幕91视频 | 日本不卡一区二区 | 欧美国产日韩一区二区 | 免费看一级黄色 | 一区二区av | 国产精品成人免费精品自在线观看 | 在线视频 亚洲 | 久久香蕉一区 | 999热视频 | 久久久久综合视频 | a黄色一级片 | 亚洲国产精品久久久 | 黄色三级视频片 | 99在线观看免费视频精品观看 | 中文在线免费一区三区 | 中文字幕一区二区三区四区在线视频 | 丝袜美女在线观看 | 国产精品第二页 | 91自拍91 | 天天综合网 天天综合色 | 808电影免费观看三年 | 天天干夜夜干 | 99久久精品一区二区成人 | 91麻豆精品国产自产在线 | 美女国内精品自产拍在线播放 | 久久国产精品久久久 | 国产一级在线免费观看 | 最近高清中文字幕 | 黄色片网站| 久久精品日产第一区二区三区乱码 | 在线观看视频97 | 亚洲 欧洲 国产 日本 综合 | 欧美日韩高清免费 | 激情五月在线视频 | 久久激情五月丁香伊人 | 国产精品福利在线观看 | 狠狠色综合欧美激情 | 精品专区 | 亚洲高清视频在线播放 | 99久热在线精品 | www免费网站在线观看 | 亚洲观看黄色网 | 久久九九精品久久 | 在线观看深夜福利 | 国产日产亚洲精华av | 一级黄色电影网站 | 一本一本久久a久久精品综合妖精 | 久草在线视频新 | 黄色av免费电影 | 国产精品视频久久 | 日韩精品一区二区三区水蜜桃 | 色综合激情网 | 91免费版在线观看 | 欧美激情亚洲综合 | 网站在线观看日韩 | 国产乱对白刺激视频在线观看女王 | 免费在线观看av片 | 6080yy午夜一二三区久久 | 人人干狠狠操 | 成年人国产在线观看 | 日韩在线视频观看 | 五月婷婷在线视频 | 一二三久久久 | 日韩免费中文字幕 | 国产视频中文字幕在线观看 | 九九久久影视 | 色播五月婷婷 | 中文字幕在线看人 | 亚洲精品视频 | 精品国产精品国产偷麻豆 | 久久私人影院 | 日韩视频中文字幕在线观看 | 中国一级特黄毛片大片久久 | 看毛片的网址 | 国产精品视频永久免费播放 | 一区二区三区免费在线观看 | 91av免费看| 国产精品美女久久久久久 | 国产精品欧美久久久久无广告 | 91精品在线麻豆 | 国产精品99爱 | 超碰97公开 | 亚洲艳情 | 色亚洲网 | 久要激情网| 色偷偷88欧美精品久久久 | 久一在线| 日韩精品专区在线影院重磅 | 国产精品综合在线 | 欧美日一级片 | 99精品一级欧美片免费播放 | 日本性生活一级片 | av免费看在线 | 深爱激情五月网 | av三级av| 麻豆国产在线视频 | 亚洲精品99久久久久中文字幕 | 日韩免费一二三区 | 欧美久久九九 | 国外成人在线视频网站 | 天天综合精品 | 久久久国产精品一区二区三区 | 99久久精品日本一区二区免费 | 久久曰视频 | 91成人观看 | 国产xx在线 | 欧美91精品| 国产手机视频在线播放 | 一级欧美黄 | 五月婷婷导航 | 综合网伊人 | 五月天堂色 | 精品视频在线免费 | 亚洲 欧美 变态 国产 另类 | 中文永久字幕 | av资源免费在线观看 | a天堂免费 | 在线色资源 | 亚洲精品欧美视频 | 亚洲精品欧美专区 | 欧美了一区在线观看 | 成人av网站在线播放 | 日批视频在线 | 高清av中文在线字幕观看1 | 免费在线观看成人 | 91免费在线视频 | 国产 日韩 在线 亚洲 字幕 中文 | 深爱婷婷网 | 91香蕉视频黄色 | 亚洲国产欧洲综合997久久, | 国产又粗又猛又黄 | 福利av影院 | 夜夜躁日日躁 | 中文字幕在线观看视频一区二区三区 | 久久婷婷国产 | 91欧美精品 | 在线观看中文字幕一区二区 | 成人黄色在线 | 天天色成人| 日韩毛片在线免费观看 | 99 精品 在线 | 视频一区亚洲 | 成人免费观看电影 | 最近中文字幕高清字幕在线视频 | 91在线中文 | 免费看色的网站 | 手机av片| 手机av在线网站 | 午夜精品一区二区三区在线视频 | 亚洲国产精品久久久久久 | 亚洲最大激情中文字幕 | 91精品啪在线观看国产线免费 | 麻豆国产精品va在线观看不卡 | 久久久久免费观看 | 玖玖国产精品视频 | 91爱爱网址 | 久久久午夜精品福利内容 | 国产成人福利在线观看 | 九月婷婷人人澡人人添人人爽 | 日本精品一区二区 | www国产一区 | 国产精品二区在线观看 | 久久久久久毛片精品免费不卡 | 中文字幕在线观看2018 | 久久免费视频在线观看6 | 久久久久久久久久久福利 | 91看片淫黄大片一级在线观看 | 在线看日韩 | 国产区高清在线 | 亚洲精品在线二区 | 国产专区欧美专区 | 欧美做受高潮电影o | 国产在线国偷精品产拍 | 免费亚洲视频在线观看 | 久 久久影院 | 91视频中文字幕 | 国产精品毛片久久久久久久久久99999999 | 成人av在线看 | 99精品国产免费久久久久久下载 | 精品国产一区二区三区久久久蜜臀 | 911香蕉| 高清av免费观看 | 成在线播放 | 日本电影黄色 | 9在线观看免费 | 国产精品一区二区吃奶在线观看 | 99久久综合精品五月天 | 九九久 | 黄色的视频网站 | 99riav1国产精品视频 | 成人国产精品一区二区 | 一区二区精品视频 | 一区二区三区国产欧美 | 高清精品久久 | 国产精品久久久久久久久岛 | 男女精品久久 | 日韩电影一区二区三区 | 亚洲国产一区二区精品专区 | 国产分类视频 | 免费看污黄网站 | 天天爱天天操天天干 | 亚洲视频在线观看 | 日韩高清精品免费观看 | 日韩中文字幕国产 | 超级av在线| 91亚洲精品久久久中文字幕 | 免费av黄色| 正在播放一区二区 | 天天干天天操天天拍 | 欧美动漫一区二区三区 | 久香蕉| 人人玩人人添人人澡97 | 一区二区三区在线电影 | 国产精品久久久久久久午夜 | 日韩a级黄色片 | 久久在线精品 | 国产高潮久久 | 欧美久久精品 | 麻豆91精品91久久久 | 深爱激情开心 | 久久伊人八月婷婷综合激情 | 手机看片中文字幕 | 干 操 插 | 亚洲一区免费在线 | 免费a网站 | 免费在线观看av电影 | 天天射天天操天天色 | 亚洲欧美日韩国产 | 91精品国产福利在线观看 | 手机av在线不卡 | 天天射夜夜爽 | 精品美女久久久久 | 日韩一区二区三区高清免费看看 | 亚洲色综合 | 天天干天天操天天干 | 日日精品 | 国产精品igao视频网入口 | 欧美电影黄色 | 六月丁香在线观看 | 美女国内精品自产拍在线播放 | 午夜视频免费播放 | 日韩午夜电影院 | 亚洲日本成人网 | 91亚洲精品乱码久久久久久蜜桃 | 狠狠色狠狠色 | 免费av片在线 | 五月天天色 | 天天色天天射天天操 | 日韩亚洲欧美中文字幕 | 国产精品18久久久久久久久 | 久9在线| 成人午夜电影网站 | av中文字幕免费在线观看 | 国产无区一区二区三麻豆 | 日韩美在线观看 | 国产中文在线观看 | 四虎成人精品在永久免费 | 91免费高清观看 | 久久免费福利 | 九九热精品在线 | 国产日韩精品一区二区在线观看播放 | 不卡的av在线 | 草樱av | 免费97视频 | 欧美国产高清 | 五月天久久 | 欧美日韩三级在线观看 | 91精品网站 | 午夜av大片 | 国产精品九九九 | 91九色成人蝌蚪首页 | 久久久激情网 | 午夜国产成人 | 国产一区二区在线视频观看 | 人操人 | 久久99国产综合精品 | 亚洲一区二区视频在线播放 | 97激情影院 | 久草在线在线精品观看 | 综合久久久久 | 久热色超碰 | 91av大全| 欧美日韩免费视频 | 97人人射| 综合色在线观看 | 精品一区二区三区香蕉蜜桃 | 婷婷久久五月天 | 久久99久久99精品免观看粉嫩 | 波多野结衣精品视频 | 日韩欧美在线中文字幕 | 久久亚洲专区 | 性色在线视频 | 操操操天天操 | 亚洲 欧美日韩 国产 中文 | 亚洲精品黄网站 | 久久69精品久久久久久久电影好 | 国产 视频 久久 | 国产一区二区视频在线播放 | 日日夜夜中文字幕 | 激情深爱.com | 精品影院| 国产色综合天天综合网 | 日韩最新中文字幕 | 国产黄影院色大全免费 | 日日夜操 | 黄色一级在线观看 | 天天操导航 | 国产成人高清在线 | 亚洲狠狠操| 久久久久麻豆v国产 | 国产精品久久久久久久久搜平片 | 九九免费在线视频 | 亚洲精品高清一区二区三区四区 | 国产精品99精品久久免费 | 97成人在线观看视频 | 国产亚洲一区二区在线观看 | 久久乐九色婷婷综合色狠狠182 | 亚洲在线视频观看 | av在线网站免费观看 | 成人中心免费视频 | 欧美日韩免费网站 | 2019免费中文字幕 | 精品国产欧美一区二区 | 日韩深夜在线观看 | 国产伦精品一区二区三区四区视频 | 亚洲精品999 | 国产裸体永久免费视频网站 | 91在线观看欧美日韩 | 欧美另类巨大 | 久久精品久久99精品久久 | 不卡电影一区二区三区 | a成人v在线 | 亚洲天堂精品视频在线观看 | 天天天天色射综合 | 久久久免费观看完整版 | 亚洲国产精品电影 | 亚洲欧美日韩一二三区 | 久久精品一区二区三区视频 | 欧美aaa大片 | 正在播放亚洲精品 | 最新色站 | 成人国产精品久久久 | 色婷婷导航| 一区二区三区日韩视频在线观看 | 中文字幕在线不卡国产视频 | 欧美日韩天堂 | 天天射天天爱天天干 | 久草在线久草在线2 | 午夜精品久久久久久久99热影院 | 狠狠躁天天躁 | 一区二区激情视频 | 婷婷在线播放 | 国产中文字幕在线免费观看 | 黄色片亚洲 | 欧美日韩不卡在线观看 | 久久精品人人做人人综合老师 | 女人18片毛片90分钟 | 手机av片| 网站免费黄 | 九九交易行官网 | 色视频在线免费观看 | 日韩一区二区免费视频 | 91在线观看高清 | 国产精品久久久久永久免费观看 | 色婷婷九月 | 天天综合日 | 国产成年免费视频 | 日韩精品一区在线播放 | 九九色网 | 在线观看免费版高清版 | 99视频精品| www.亚洲在线 | 五月天激情电影 | 人人玩人人添人人澡97 | 日韩国产欧美在线播放 | 友田真希x88av | 香蕉在线观看视频 | 韩国av在线播放 | 超碰在线色 | 欧美韩国日本在线 | av丝袜美腿| 日日夜夜骑 | 日韩精品专区在线影院重磅 | 国产亚洲精品中文字幕 | 国产 日韩 欧美 中文 在线播放 | 黄色成人av网址 | 亚洲女欲精品久久久久久久18 | 久久av免费 | 91完整版观看 | 一区二区免费不卡在线 | 久草视频在线播放 | 狠狠狠狠狠狠狠狠干 | 久久精品毛片基地 | 奇米网8888| 99精品免费久久久久久日本 | 最新国产在线观看 | 日韩在线视频网 | 免费一级片在线 | 久草在线观 | 98超碰在线观看 | 国产精品久久久久久高潮 | 日韩在线观看小视频 | 欧美日韩国产一区二区三区在线观看 | 一区二区三区四区免费视频 | 日日夜夜爱 | 又黄又刺激的网站 | 午夜国产在线观看 | zzijzzij亚洲日本少妇熟睡 | 不卡的av在线| 玖玖精品在线 | 国产一区二区在线免费播放 | adc在线观看 | 亚洲乱码久久久 | 日韩在线视频观看 | 夜夜躁狠狠燥 | 色99色| 日韩av片无码一区二区不卡电影 | 免费久久99精品国产婷婷六月 | 婷婷在线色 | 午夜美女wwww | 国产一级二级在线观看 | 久久婷婷精品视频 | 最新国产精品亚洲 | 西西www4444大胆在线 | 日本久久精品 | 久久福利影视 | 国内外成人在线视频 | 国产一区自拍视频 | 国产亚洲精品久久 | 99热在线这里只有精品 | 天堂av免费观看 | 中文字幕视频播放 | 日本女人b | 精品视频区 | 成年一级片 | 国产美女久久久 | 全黄网站| 一本一本久久a久久精品综合小说 | 在线观看www91 | 狠狠狠色丁香综合久久天下网 | 成人午夜电影免费在线观看 | 亚洲午夜剧场 | 最新中文字幕在线观看视频 | 日韩美女高潮 | 特黄色大片| 久久久国产视频 | 国产在线播放观看 | 成人黄色毛片视频 | 国产精品中文字幕在线观看 | 国产在线视频一区 | 久久蜜臀一区二区三区av | 九九热视频在线免费观看 | 偷拍精品一区二区三区 | 日日久视频 | 九九九视频精品 | 最新av在线播放 | 美女视频永久黄网站免费观看国产 | 国产精品自产拍 | 日韩精品在线一区 | 热久久影视| 久久伊人爱 | 亚洲极色 | 亚洲涩涩网站 | 丁香网五月天 | 成人免费观看a | 日韩美在线 | 久久这里精品视频 | 国产精品一区二区在线免费观看 | 亚州av成人| 国产精品av免费在线观看 | 激情视频久久 | 深爱激情五月网 | 九九九九热精品免费视频点播观看 | 天天操夜夜爱 | 草久久久久久 | 久久综合激情 | 香蕉视频色 | 久久精品网址 | 欧美成人精品三级在线观看播放 | 91麻豆精品91久久久久同性 | 免费观看91视频大全 | 美女免费网站 | 国产精品99久久免费黑人 | 国产精品99久久久久久久久 | 天天干夜夜擦 | 一级片色播影院 | 中文字幕 成人 | 99精品观看 | 蜜桃av久久久亚洲精品 | 日韩黄色免费 | 亚洲一级久久 | 欧美国产日韩在线视频 | 五月天电影免费在线观看一区 | 精品一区久久 | 毛片无卡免费无播放器 | 国产精品免费久久久久影院仙踪林 | 国产在线精品福利 | 在线观看日韩免费视频 | 久久草草影视免费网 | 综合久久久 | 91香蕉视频污在线 | 欧美精品中文 | 丁香六月色 | 日日摸日日碰 | 精品亚洲男同gayvideo网站 | 成人在线一区二区 | 国产成人久久久77777 | 国产精品免费不 | 亚洲国产高清在线 | 久久久受www免费人成 | 国产亚洲人 | 成人午夜黄色影院 | 日本精品一区二区三区在线播放视频 | 色综合小说 | 国产一级在线视频 | 久久五月天综合 | 欧美先锋影音 | 国产精品久久久久免费a∨ 欧美一级性生活片 | 激情综合色图 | 人人射人人爽 | 日韩久久激情 | 97成人免费视频 | 欧美极品xxx | 精品国产一二三四区 | 国产成人av一区二区三区在线观看 | 亚洲涩涩网 | 色综合在 | 激情久久久久 | 日本免费一二三区 | 国产一区二区三区免费观看视频 | 成人免费xxx在线观看 | 黄色特级一级片 | 国产精品久久久亚洲 | 日韩黄色在线电影 | 在线观看免费高清视频大全追剧 | 色天天综合久久久久综合片 | 色资源二区在线视频 | 国产精品成人国产乱一区 | 91视频久久久 | 亚洲最新在线视频 | 2023av在线| 韩国av一区二区三区在线观看 |