成人性生交大片免费看视频r_亚洲综合极品香蕉久久网_在线视频免费观看一区_亚洲精品亚洲人成人网在线播放_国产精品毛片av_久久久久国产精品www_亚洲国产一区二区三区在线播_日韩一区二区三区四区区区_亚洲精品国产无套在线观_国产免费www

主頁 > 知識庫 > 使用Lua來擴(kuò)展C++程序的方法

使用Lua來擴(kuò)展C++程序的方法

熱門標(biāo)簽:昆明電話外呼系統(tǒng)好么 免費(fèi)門店地圖標(biāo)注注冊入駐 陜西便宜電銷機(jī)器人軟件 艾比利外呼系統(tǒng) 海口智能語音電銷機(jī)器人好用嗎 衡水外呼線路解決 電話機(jī)器人每天搜索多少次 杞縣地圖標(biāo)注app 外呼系統(tǒng)一天耗費(fèi)多少流量

 介紹

如果用戶能夠通過一些腳本語言來修改應(yīng)用本身的行為,那么許多應(yīng)用可以變得更適合用戶使用。一些商業(yè)應(yīng)用就提供了此類便利。例如 Microsoft Office 的 VBA 腳本編程或在視頻游戲 World of Warcraft 中使用 Lua 。腳本語言把應(yīng)用作為一個平臺提供一系列終端用戶可以獲得并操控的服務(wù)。

做為嵌入到程序中的語言,我們有很多可用的選擇:開源和不開源的腳本引擎,或者可以從頭開始創(chuàng)建一個。現(xiàn)在,最為熟知的腳本語言是JavaScript,Lua和Python,還有很多其它的語言等等。在Microsoft Windows平臺上 嵌入腳本引擎的一般方法是使用一個 包含腳本引擎動態(tài)鏈接庫(DLL)中,然后使用一系列的函數(shù)調(diào)用訪問引擎中的服務(wù)。

在這篇文章里面我們將看到如何使用lua5.2腳本引擎嵌入到C++的代碼中,我們的測試用例使用的開發(fā)工具是Visual Studio 2005.這開始講解之前我們要從lua官方網(wǎng)站下載一些必要的組件,lua5.2中包含有已經(jīng)編譯好的dll以及頭文件和鏈接用的導(dǎo)入庫。需要說明的是當(dāng)你使用lua嵌入到C++代碼的時候,編譯出來的可執(zhí)行文件必須包含有l(wèi)ua的DLL即動態(tài)鏈接庫,否則會提示運(yùn)行出錯,缺少必要的dll。這些例子都是用Visual Studio 2005編寫,當(dāng)然對于VS的后續(xù)版本是兼容的。


這篇文章向您描述了一個使用lua5.2作為腳本引擎的特定實(shí)現(xiàn),在lua的官方文檔(lua.org)以及一些網(wǎng)站中有許多關(guān)于這方面的信息,這里僅僅是為你提供一些測試?yán)樱鳛槟汩_始lua旅程之前的引導(dǎo)

對于產(chǎn)品開發(fā)而言,開發(fā)一個完整專業(yè)應(yīng)用程序跟開發(fā)單塊應(yīng)用程序有不同的策略和方法。譬如說:開發(fā)完整專業(yè)應(yīng)用平臺需要對終端用戶提供大量豐富的插件工具和服務(wù)去實(shí)現(xiàn)他們自己特定的領(lǐng)域需求。插件程序的策略和方法被應(yīng)用在許多的軟件中,例如微軟的Office,Visual Studio以及集成開發(fā)環(huán)境Eclipse,甚至是圖片處理軟件Adobe Photoshop. 網(wǎng)游魔獸世界就提供大量的add-on(插件)給用戶,一些其他的游戲提供類似的工具,讓玩家可以增加額外的內(nèi)容從而創(chuàng)造一個與眾不同的社區(qū)。


作為商業(yè)應(yīng)用程序,GenPOS,有一些特性也是極具工具集的策略的:

  •     布局管理器工具然該用戶可以通過調(diào)整窗口,按鈕的位置,文字,內(nèi)容等屬性來調(diào)整界面的布局。
  •     字符控制功能可以讓一些工作流自動化
  •     豐富的參數(shù)化設(shè)計可以更改軟件的功能
  •     數(shù)據(jù)庫的助記符可以使得顯示不同的語言,使得多語言更容易
  •     通過遠(yuǎn)程接口可以動態(tài)地改變參數(shù)和助記符
  •     提供接口從終端獲取財物和運(yùn)行的狀態(tài)數(shù)據(jù)


不管怎樣,有些模塊是被源代碼實(shí)際控制的,這部分模塊的更改需要通過開發(fā)部門的協(xié)作才能完成軟件行為的改變。例如說,打印收據(jù)(一些顯示內(nèi)容是從參數(shù)或者助記符的輸入中獲取的)。簡短列舉這些限制可能包含:

  •     現(xiàn)有的字符控制功能缺少狀態(tài)測試和跳轉(zhuǎn)
  •     不能溝通動態(tài)地根據(jù)現(xiàn)有的狀態(tài)修改和顯示信息

與其試圖加強(qiáng)和改進(jìn)當(dāng)前的非常簡單的控制字符串功能,以提供包含額外腳本功能的銷售終端,我們最終決定尋找到其它可能的方案,不需要大量開發(fā)到改進(jìn),且提供更多的產(chǎn)品改進(jìn)能力。就像我們引入的布局管理器使客戶能夠設(shè)計自己的屏幕布置和工作流程一樣,我們希望有一個相當(dāng)靈活的機(jī)制讓經(jīng)銷商的銷售終端通過腳本為他們的客戶提供增值服務(wù)。我們還打算提供足夠的應(yīng)用服務(wù)訪問權(quán)限,讓經(jīng)銷商和最終客戶將能夠修改自己的應(yīng)用程序的行為。最后,我們要使用有一定程度到用戶社區(qū)的語言,感興趣到人們可以使用社區(qū)的資源。

我們已經(jīng)用5.2版本的Lua腳本引擎在POS源代碼上做了一些簡單的實(shí)驗來觀察向程序中添加功能的難度。從實(shí)驗結(jié)果來看,我們想通過程序服務(wù)來展現(xiàn)的各種功能已經(jīng)是可用的了,并且可以通過對Lua腳本引擎做一些修改就可以使用起來。

使用 Lua 5.2 腳本引擎

Lua 腳本引擎本身是由 C 語言寫成的,在 C 或 C++ 中使用 Lua 腳本也相當(dāng)簡單。你在網(wǎng)上也可以找到很多集成了 Lua 5.2 腳本引擎的的程序或程序片段,并且 Lua 5.2 的程序接口和先前 Lua 版本只有在初始化和啟動等接口上存在少量變化,所以舊的 Lua 程序可以不做修改或只做很小的修改就可以移植到 Lua 5.2環(huán)境下。


基本的初始化步驟如下:

  •     使用 lua_newstate() 創(chuàng)建一個新的 Lua 狀態(tài)機(jī)。
  •     若有必要,調(diào)用 luaL_openlibs() 函數(shù)加載 Lua 的標(biāo)準(zhǔn)庫。

一旦初始化了 Lua 腳本引擎,你可以通過如下步驟執(zhí)行一段 Lua 腳本:

  •     使用 luaL_loadfile 加載一段 Lua 程序或腳本到 Lua 執(zhí)行引擎中;
  •     調(diào)用 lua_pcall 函數(shù)執(zhí)行已加載的腳本。

如果想在應(yīng)用程序中加載Lua腳本并執(zhí)行其中的函數(shù),你必須執(zhí)行被加載的Lua程序塊(chunk)。剛剛加載的程序塊只是編譯后存放于Lua的腳本引擎中,并沒有被執(zhí)行。只有在程序塊被執(zhí)行后,Lua中的全局變量和函數(shù)才會被創(chuàng)建,在這之前這些任何全局變量和函數(shù)對于應(yīng)用程序來說都不可用。作為Lua引擎的環(huán)境由應(yīng)用程序提供給Lua腳本引擎的任何全局變量和函數(shù)也不可用。應(yīng)用程序必須首先創(chuàng)建變量和函數(shù),并使用函數(shù)lua_setglobal()讓它們可用。在文件 UtilityFunctions.cpp 中的函數(shù)int LuaSimpleWrapper::TriggerGlobalCall()定義了一個例子,它在Lua虛擬棧上動態(tài)創(chuàng)建一個Lua函數(shù)調(diào)用,并用Lua腳本引擎中的lua_pcall()函數(shù),以給定的參數(shù)來執(zhí)行此函數(shù)。

所有Lua腳本引擎函數(shù)或服務(wù),都用到一個包含Lua腳本引擎狀態(tài)信息的句柄或數(shù)據(jù)結(jié)構(gòu)指針。這個句柄被指定為lua_State*或者指向lua_State變量的指針。每次成功的lua_newstate()的調(diào)用都會返回一個lua_State指針,失敗時返回NULL。這個數(shù)據(jù)結(jié)構(gòu)是用來指示特定會話的變量,它允許Lua腳本引擎同時有多個會話并行。當(dāng)應(yīng)用程序用到Lua腳本引擎中的函數(shù),或應(yīng)用程序提供給Lua腳本引擎的服務(wù)被調(diào)用時,lua_State結(jié)構(gòu)提供的會話環(huán)境唯一指示了某個Lua會話狀態(tài)。這意味著,應(yīng)用程序提供給Lua腳本引擎的函數(shù)應(yīng)該是完全可重入的,或者提供某種監(jiān)視,比如信號量和臨界區(qū)使得非共享服務(wù)能夠提供線程安全的訪問。

使用代碼

在Visual Studio 2005工程目錄中包含三個C++文件和一個測試基本功能的Lua例子。主體部分在Parser01.cpp中。在這里,加載了特定的Lua文件,然后又調(diào)用了一些別的函數(shù)。UtilityFunctions.cpp包含了LuaSimpleWrapper方法的源代碼。InitEnviron則包含了我們希望提供給Lua環(huán)境的的函數(shù)。

我們正考慮使用的這個方法是, 在銷售點(diǎn)應(yīng)用程序啟動一個包含Lua腳本的文件被指定。作為啟動,銷售點(diǎn)將啟動一個初始化Lua腳本引擎并且加載和執(zhí)行指定的Lua源文件的線程。Lua塊將一直保留在內(nèi)存中,并且在銷售點(diǎn)應(yīng)用程序中,隨著事件的進(jìn)行一些事件會被轉(zhuǎn)移到Lua腳本進(jìn)行處理。這個示例程序中的測試工具是一個對我們正在考慮的這種方法的探索。

在下面提供的lua源碼的函數(shù)中,我們使用了幾個在文件InitEnviron.cpp中提供的幾個函數(shù),處理非標(biāo)準(zhǔn)Lua字符串的‘寬字符串'。標(biāo)準(zhǔn)的Lua字符串是char字符串(C風(fēng)格的單字節(jié)字符串)。這些附加函數(shù)為Lua處理這些寬字符串提供了方法,例如字符串的連接,比較。


下面展示一個含有三個參數(shù)并執(zhí)行一系列操作的Lua函數(shù)。函數(shù)名xxfunc是一個全局名字,應(yīng)用程序可以通過調(diào)用函數(shù)lua_getglobal()從Lua全局字典中檢索出來并在Lua虛擬堆棧上把句柄傳給lua_getglobal。然后函數(shù)的參數(shù)可以通過調(diào)用像一個lua_pushstring()的函數(shù)推送到Lua虛擬堆棧上,接著調(diào)用Lua腳本引擎函數(shù)lua_pcall()執(zhí)行xxfunc函數(shù)。

復(fù)制代碼 代碼如下:
-- a sample Lua global function that can be invoked from the application or from Lua
function xxfunc (myMessage, wide1, wide2)
    trace("## xxfunc() called.")
    trace("  "..myMessage)
    trace ("  myFrame index "..myFrame.FrameIndex)
    trace ("  myFrame2 index "..myFrame2.FrameIndex)
    trace ("  myFrame3 index "..myFrame3.FrameIndex)
   
    -- compare two wide char strings that were passed in as arguments
    trace ("  compare wide "..wcscmp(wide1, wide2))
   
    -- generate a wide char string from a Lua string
    local widestring = wcscre("WIDE1")
    trace ("  compare with generated "..wcscmp (wide1, widestring))
   
    -- try out the wcscat and the wcscre functions to generate a string
    traceW (wcscat (wcscre("  concat two "), wcscat(wide1, wide2)))
   
    traceW (wcscat (wcscre("  concat multi "), wide1, wcscre(" "), wide2))
   
    -- tryout wcscat with a non-string argument which should be skipped.
    traceW (wcscat (wcscre("  concat multi "), 2, wcscre(" "), wide2))
  
    local myMemEntry = GetMnemonic (15)
    if (myMessage) then
        if (myMessage.Type == "FRAMEWORK") then
            local myNem = GetMnemonic (20)
        end
    end
end


以上在Lua腳本中已經(jīng)被加載的Lua函數(shù)可以被應(yīng)用程序調(diào)用。使用來自LuaSimpleWrapper類中的一個助手函數(shù),我們可以調(diào)用帶有以下C++代碼行的Lua函數(shù)。方法TriggerGlobalCall()需要一個標(biāo)識全局Lua函數(shù)(函數(shù)或賦給一個變量或表實(shí)例的函數(shù))的描述性字符串來調(diào)用帶有描述的參數(shù)類型。這些參數(shù)遵循描述性字符串。這種類型的變量函數(shù)調(diào)用會成為一個運(yùn)行時錯誤的根源,因為它包含幾個單獨(dú)的必須匹配的源:

1. TriggerGlobalCall()中的描述性字符串;
2. theTriggerGlobalCall()提供的實(shí)際參數(shù);
3. 被調(diào)用的Lua函數(shù)。

復(fù)制代碼 代碼如下:
if (myLua.TriggerGlobalCall ("xxfunc:s,w,w", "TriggerGlobalCall", L"WIDE1", L"WIDE2") 0) {
    cout "%% " myLua.GetLastErrorString() endl ;
}


富有表達(dá)力的字符串使用了由逗號分隔的列表來區(qū)分參數(shù)的類型,列表中每個字母代表著各自的類型,如一個ANSI字符串,一個長字符串,一個浮點(diǎn)型,一個整型,一個函數(shù)的地址。在 TriggerGlobalCall() 方法的代碼中,字母中間的逗號被忽略了,實(shí)際上他們存在的作用只是為了使這個富有表達(dá)力的字符串更易識別和理解。

上面的方法TriggerGlobalCall()調(diào)用了Lua的xxfunc()函數(shù)會產(chǎn)生如下的結(jié)果輸出。這輸出由Lua函數(shù)使用TriggerGlobalCall()里定義的參數(shù)列表的參數(shù)生成。

復(fù)制代碼 代碼如下:
## xxfunc() called.
  TriggerGlobalCall
  myFrame index 0
  myFrame2 index 1
  myFrame3 index 2
  compare wide -1
  compare with generated 0
  concat two WIDE1WIDE2
  concat multi WIDE1 WIDE2
  concat multi  WIDE2
  getTransactionMnemonic() 15


我們在LuaSimpleWrapper 類中提供的TriggerGlobalCall()方法允許指定一個可訪問一個函數(shù)的表值,這個函數(shù)已經(jīng)在Lua表中分配了一個鍵值。描述性字符串的格式是:tablename.key,這里“tablename”是一個Lua表的全局名而“key”是訪問函數(shù)所需的鍵值。
 

復(fù)制代碼 代碼如下:

// specify a function to be invoked by the OnEvent() handler
// specify a different event type which is not in the Lua script
if (myLua.TriggerGlobalCall ("myFrame2.OnEvent:s,f", "EVENT_TYPE_J2", SimpleFunc) 0) {
    cout "%% " myLua.GetLastErrorString() endl;
}

將C/C++函數(shù)導(dǎo)出到Lua引擎中

為了創(chuàng)建一個要在Lua腳本中使用的C或者C++輔助函數(shù),C/C++應(yīng)用程序就必需提供該函數(shù)體(the function body)并使用適當(dāng)?shù)腖ua引擎函數(shù)讓該新函數(shù)變?yōu)樵贚ua引擎中可用。在應(yīng)用程序里將一個函數(shù)提供給在Lua引擎中進(jìn)行使用所需的函數(shù)調(diào)用要將若干值壓入Lua的虛擬堆棧之中,然后調(diào)用lua_setglobal()函數(shù),就可以把應(yīng)用程序中的函數(shù)作為全局函數(shù)提供給在Lua腳本引擎中使用。
 

復(fù)制代碼 代碼如下:

lua_pushcclosure (lua, concatMultiWideStrings, 0);
lua_setglobal (lua, "wcscat");


Lua為函數(shù)提供閉包概念。當(dāng)一個Lua腳本引擎調(diào)用應(yīng)用函數(shù)時,一個閉包允許一個應(yīng)用指定一個或多個提供給應(yīng)用函數(shù)的值。這些值可以被應(yīng)用函數(shù)更新,這個例子使用的一個特性是通過一個與應(yīng)用函數(shù)關(guān)聯(lián)的計數(shù)器增量提供一個惟一值。C++關(guān)于這方面的源代碼的一個例子可以在方法int LuaSimpleWrapper::InitLuaEnvironment()中找到,這個方法為Lua腳本引擎提供CreateFrame()函數(shù)。

復(fù)制代碼 代碼如下:
// CreateFrame() function that will create a frame with an index
// This function uses two variables which are used to store the
// frame data allowing it to be used by the application in order to
// send events to a specific frame object in the Lua code.
// we access the array of the list of objects, m_ListOfObjects[], with objectindex
// and we access the specific frame for the object with frameindex.
lua_pushnumber(m_luaState, 0);                // frameindex, count of frames for this Lua state object, init to zero
lua_pushnumber(m_luaState, m_MyObjectCount);  // objectindex, which Lua state object am I?

// create the C closure with the above two arguments,
lua_pushcclosure (m_luaState, ParserLuaCreateGlobalFrame, 2);
lua_setglobal (m_luaState, "CreateFrame");


要導(dǎo)出的C++函數(shù)的源代碼應(yīng)該具有如下所示的形式。函數(shù)concatMultiWideStrings ()使用了一系列的Lua引擎里的函數(shù)處理LUa虛擬堆棧之中的一些數(shù)值并將處理結(jié)果返回給Lua引擎。以下所示函數(shù)說明了要使用lua_State *這個參數(shù)提供給該函數(shù)相關(guān)的session環(huán)境。這個函數(shù)用以將多個字符串拼接到一起。Lua腳本引擎提供了位于Lua虛擬堆棧之中的參數(shù)的個數(shù)信息。我們還可以使用Lua引擎提供的lua_type()函數(shù)判斷出參數(shù)的數(shù)據(jù)類型,從而可以跳過那些不是正確類型的參數(shù)。
 

然而,實(shí)際上在我們只想使用LUA_STRING這種類型的情況下,Lua腳本引擎會執(zhí)行相應(yīng)的類型轉(zhuǎn)換,但Lua所做的從其它類型到字符串類型的轉(zhuǎn)換的結(jié)果是C風(fēng)格的單字節(jié)字符所組成的字符串串而不是我們所預(yù)期的雙字節(jié)寬度的字符組成的字符串。
 

復(fù)制代碼 代碼如下:
// concatenate multiple wide strings
//  const wchar_t *wcscat(wchar_t *wcharSt1, const wchar_t *wcharSt2, const wchar_t *wcharSt3, ...)
static int concatMultiWideStrings (lua_State *lua)
{
    int  nPushCount = 0;
    int  nArgIndex = 1;
    int argc = lua_gettop(lua);
    wchar_t  tempBuffer[2048];
 
    if (argc > 0) {
        wchar_t    *pWideString = tempBuffer[0];
        size_t     iLen = 1;
 
        while (nArgIndex = argc) {
            if (lua_type(lua, nArgIndex) == LUA_TSTRING) {
                const wchar_t *msgX = (wchar_t *) lua_tostring (lua, nArgIndex);
                while (*msgX) {*pWideString++ = *msgX++; iLen++; }
            }
            nArgIndex++;
        }
        *pWideString = 0;  // final zero terminator
        lua_pushlstring (lua, (char *)(tempBuffer), iLen * sizeof(wchar_t));
        nPushCount++;
    }
 
    return nPushCount;
}

關(guān)注點(diǎn)

該測試工具(test harness)的第一個版本只是個非常簡單的開頭,只是簡單的裝載一個簡單Lua腳本,在運(yùn)行后也只是使用Lua的輸出函數(shù)在控制臺(console)中輸出一個“Hello World”。隨著在調(diào)查嵌入式Lua所具有的潛在能力時,腳本和測試工具會變得越來越復(fù)雜,很快就會發(fā)現(xiàn)明顯需要有某種方式將Lua虛擬堆棧中所有內(nèi)容打印出來,才能理解Lua引擎同應(yīng)用程序之間到底是如何進(jìn)行通信的。 要多次在運(yùn)行突然中斷,使用調(diào)試器單步進(jìn)入C++源代碼時使用堆棧內(nèi)容輸出函數(shù)查看堆棧中內(nèi)容,只有這樣才能理解到底發(fā)生了什么問題并找出問題的修復(fù)辦法。

Lua語言的動態(tài)特性,像JavaScript這類的松散類型語言一樣,會鼓勵有冒險精神的程序員寫出一些非常有趣的代碼,但是也會產(chǎn)生一些非常難以調(diào)試和測試的代碼。這個難度主要來自于使用了兩種語言,而在Visual Studio中又缺乏對Lua調(diào)試的支持。


在實(shí)現(xiàn)方法int LuaSimpleWrapper::TriggerGlobalCall ()時,在Visual Studio debugger里運(yùn)行的情況下我們遇到了導(dǎo)致Lua的腳步引擎(script engine)在Windows錯誤對話框中要執(zhí)行應(yīng)用程序關(guān)閉或退出操作的測試案例(test case)。我們認(rèn)為,之所以出現(xiàn)這個問題,是由于在出現(xiàn)了錯誤的情況下,有些特定的值被壓入了Lua的虛擬堆棧之中,從而未被恰當(dāng)處理所導(dǎo)致的。為了解決該問題,在發(fā)現(xiàn)錯誤的情況下,我們要用下面所示的C++代碼對Lua的虛擬堆棧進(jìn)行清理。在此測試套件(test harness)中,我們有兩個不同的測試,一個用來對指定的全局變量是否存在進(jìn)行測試,另一個測試的是,如果通過使用“global.key”語法指定了一個關(guān)鍵值(key value),那么其中的全局變量必定為一個表,否則便為錯誤。

復(fù)制代碼 代碼如下:
 
lua_getglobal (m_luaState, globalName);
if (lua_type(m_luaState, lua_gettop(m_luaState)) == LUA_TNIL) {
    // if the global variable does not exist then we will bail out with an error.
    strcpy_s (m_lastLuaError, sizeof(m_lastLuaError), "Global variable not found: ");
    strcat_s (m_lastLuaError, sizeof(m_lastLuaError), globalName);
    m_lastState = LuaDescripParse;
    // error so we will just clear the Lua virtual stack and then return
    // if we do not clear the Lua stack, we leave garbage that will cause
    // problems with later function calls from the application.
    // we do this rather than use lua_error() because this function is called
    // from the application and not through Lua.
    lua_settop (m_luaState, 0);
    return -1;
}

您可能感興趣的文章:
  • Lua和C/C++互相調(diào)用實(shí)例分析
  • C++利用LuaIntf調(diào)用Lua的方法示例
  • Lua中調(diào)用C++函數(shù)示例
  • 把Lua函數(shù)傳遞到C/C++中實(shí)例
  • Lua和C++語言的交互詳解
  • C++與Lua交互原理實(shí)例詳解

標(biāo)簽:宿遷 昌都 南京 泰安 營口 西寧 臨滄

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《使用Lua來擴(kuò)展C++程序的方法》,本文關(guān)鍵詞  使用,Lua,來,擴(kuò)展,C++,程序,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《使用Lua來擴(kuò)展C++程序的方法》相關(guān)的同類信息!
  • 本頁收集關(guān)于使用Lua來擴(kuò)展C++程序的方法的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    丰满人妻一区二区三区53号| 久久丫精品忘忧草西安产品| 亚洲一区在线看| 99久久精品国产亚洲| 又色又爽又黄无遮挡的免费视频| 91福利视频导航| 不卡视频在线观看| 久久av电影| 免费看黄色av| 丝袜美腿中文字幕| 公共露出暴露狂另类av| 亚洲欧美国产一区二区三区| 一本色道无码道dvd在线观看| 日本成人黄色网| 麻豆国产高清在线播放| 一级黄色大毛片| 内射国产内射夫妻免费频道| 国产一区二区按摩在线观看| 北条麻妃在线一区二区| 天天做天天摸天天爽天天爱| 欧美在线二区| 呻吟揉丰满对白91乃国产区| 日韩精品欧美成人高清一区二区| 国产精品极品尤物在线观看| 亚洲女同一区二区| 男人天堂1024| 欧美亚洲视频一区二区| 视频在线99| 美女黄色网址| 久久久久高潮毛片免费全部播放| 久久久久久久久97黄色工厂| 91成人免费电影| 成人黄色国产精品网站大全在线免费观看| 久久精品男人天堂av| 可以免费在线看黄的网站| 日本高清在线观看视频| 韩剧1988免费观看全集| av影片在线播放| 欧美福利视频导航| 日韩一二三区视频| 亚洲天堂中文网| 中文字幕在线观看网站| 美女做爰内谢全过程视频| 国产日韩精品一区二区三区在线| 一级片视频网站| 欧美一区二区三区视频| 欧美一级视频在线观看| 国产一级免费视频| 国产一区二区三区在线观看| 国产成人免费视频一区| 国产精品电影| 亚洲精品欧美日韩| 欧美va亚洲va国产综合| 欧美日韩在线不卡一区| 中文一区一区三区高中清不卡| 久久网一区二区| 天天影视色香欲综合网天天录日日录| 欧美激情在线有限公司| 欧美 日韩 国产 激情| 狠狠色噜噜狠狠| 国模一区二区三区私拍视频| 亚洲一区二区视频在线播放| 在线电影欧美日韩一区二区私密| 五十路亲子中出中文字幕| 欧美日韩性在线观看| 中文字幕欧美日韩va免费视频| 国产麻豆一区二区三区精品| 四虎在线免费观看| 国内精品**久久毛片app| 日本一道本久久| 亚洲欧洲性图库| 久久青草福利网站| 视频在线一区二区三区| 亚洲成人tv| 国产精品美女www爽爽爽视频| 国产成人久久久| 日本一区二区三区电影免费观看| 丰满大乳奶做爰ⅹxx视频| 熟妇高潮一区二区高潮| 国产高清视频在线| 亚洲综合在线五月| 你懂得影院夜精品a| 护士精品一区二区三区| 国产精品国产三级国产aⅴ浪潮| 777a∨成人精品桃花网| 欧美精品一区二区三区蜜桃视频| 午夜免费视频网站| 国产丝袜控视频在线观看| 欧美黄色成人网| 妖精视频一区二区| 黄色激情在线观看| 一区二区欧美亚洲| 欧美oldwomenvideos| 伊人久久大香线蕉综合网蜜芽| 国产国产人免费人成免费视频| 一级毛片在线观| 九色精品免费永久在线| 中文字幕一区二区三三| 欧美电影一区二区| 中文字幕一区二区三中文字幕| 久久黄色精品视频| 777精品久无码人妻蜜桃| 久久视频在线观看| aa一级黄色片| 日本视频在线免费观看| 免费观看不卡av| 99久久免费精品| 午夜免费福利视频在线观看| 欧美日韩精品久久| 国产成人在线亚洲欧美| 韩日午夜在线资源一区二区| 欧美国产专区| 欧美综合色免费| 97久久综合精品久久久综合| 日本不卡视频一区二区| 日韩视频在线视频| 日韩国产精品大片| 国产一区二区三区综合| 天堂网avav| 亚洲影影院av| 亚洲欧美另类小说视频| 久久涩涩网站| 国产福利三区| 日韩国产高清影视| 欧美在线视频一二三| 亚洲天堂av综合网| 青青草手机视频在线观看| 成人免费视频77777| 国产精品久久久久久亚洲av| 欧美aa免费在线| 国产成人午夜性a一级毛片| 黄页网址大全在线播放| 免费色视频在线观看| 欧美丝袜丝交足nylons| 57pao成人永久免费| 国产男女猛烈无遮挡a片漫画| 欧美日韩精品一区视频| 亚洲欧美自拍偷拍色图| 又黄又爽无遮挡| 色综合色综合色综合色综合| 黄色综合网址| 欧美男男freegayvideosroom| 午夜久久电影网| 在线观看的日韩av| 天天做夜夜做人人爱精品| 久久久久久久少妇| 成人写真福利网| 亚洲天堂av一区二区三区| 欧美精品手机在线| 制服.丝袜.亚洲.中文.综合懂| 熟女少妇一区二区三区| 亚洲精品免费在线视频| 国产原厂视频在线观看| 亚洲午夜精品一区二区国产| 欧洲精品乱码久久久久蜜桃| 又大又硬又爽免费视频| 久久综合999| 久久这里只有精品1| 99久久免费精品高清特色大片| 自拍偷拍亚洲区| 美女视频a黄免费| 亚洲黄色成人网| 无码人妻一区二区三区一| 久久高清无码视频| 天堂俺去俺来也www久久婷婷| 婷婷色在线播放| 日韩精品卡通动漫网站| 欧美性受极品xxxx喷水| 久久.com| 国产免费999| 色一情一乱一区二区| 91黄色国产视频| 亚洲黄色免费网站| 精品熟妇无码av免费久久| 巨胸喷奶水www久久久免费动漫| 久热精品在线| 色黄视频在线| 国产精品一区二区三区99| 久久久久久无码午夜精品直播| 国产成人综合网| 国产aⅴ精品一区二区三区色成熟| 777久久精品一区二区三区无码| 在线观看亚洲| 日本五十肥熟交尾| 蜜桃视频成人m3u8| 羞羞视频网页| 日本道精品一区二区三区| 一区二区三区四区视频在线观看| 女同互忝互慰dv毛片观看| 国产精品免费久久| 色视频在线观看在线播放| 91香蕉嫩草影院入口| 久久国产三级| 国产va亚洲va在线va| 中国一区二区三区| 五月天婷婷激情视频| 日韩主播视频在线| 日本天堂网在线| 香港三级经典全部种子下载| 丁香社区五月天| 亚洲中文一区二区| 超碰超碰超碰超碰超碰| 中文字幕一区二区三区在线播放| 亚洲日本中文字幕在线| 免费91视频| 成人中文字幕av| 夜夜嗨av一区二区三区四区| av日韩免费电影| 亚洲国产精品福利| 嫩草懂你的影院| 免费污污网站| 伊人春色之综合网| 国产视频一区二区视频| 亚洲av电影一区| 欧美.日韩.国产.一区.二区| 日韩综合第一页| 久久久久久18| 欧美日韩一区成人| 免费中文字幕| 91丝袜超薄交口足| 91九色02白丝porn| 色吊丝在线永久观看最新版本| 日韩av黄色网址| 国产欧美韩国高清| 国产精品天干天干在观线| 久久不卡国产精品一区二区| 福利在线视频导航| 成人黄色综合网站| 一级片手机在线观看| 亚洲国产aⅴ成人精品无吗| 亚洲精品555| 真实的国产乱xxxx在线91| 亚洲综合小说图片| 欧美精品国产白浆久久久久| 国产精品扒开腿做爽爽爽软件| 久久亚洲精品国产| 青春娱乐分类视频精品2动漫| 中文字幕日韩精品一区| 免费在线观看a级片| 国产一区二区在线观看免费播放| 国产极品模特精品一二| 国产精品视频在线免费观看| 白嫩少妇丰满一区二区| av先锋影音少妇| 欧美高清在线观看| 亚洲国产美女视频| 国产精品白丝jk喷水视频一区| 国产免费一区二区三区香蕉精| 欧美乱妇高清无乱码| 欧美色综合网| 玖草视频在线| 亚洲一区免费| 久久久久久久国产视频| 成人丝袜视频网| 亚洲欧美成人| а天堂中文最新一区二区三区| 麻豆av一区二区| 一道本在线视频| 在线观看黄色片| 欧美va亚洲va日韩∨a综合色| 夜夜嗨av一区二区三区中文字幕| 99re只有精品| 国产成人77亚洲精品www| 波多野在线播放| 亚洲小说欧美另类婷婷| 日本三级片在线观看| 一级在线观看| 天堂av资源在线观看| 欧美图片激情小说| 围产精品久久久久久久| 中文字幕精品久久久久| 成人网页在线免费观看| 亚洲综合视频1区| 亚洲国产高潮在线观看| jizzyou欧美16| bl视频在线免费观看| 麻豆三级在线观看| 一区二区三区国产好的精华液| 自由日本语亚洲人高潮| 色乱码一区二区三区88| 波多野结衣在线网址| 白浆在线视频| 午夜精品三级视频福利| 国产亚洲一卡2卡3卡4卡新区| 免费黄色av网址| 久久亚洲图片| 亚洲精品黄网在线观看| 精品欧美一区二区久久| 天天综合天天做| 最新av免费在线观看| 国产精品夜间视频香蕉| 五月天中文字幕在线| 中国毛片直接看| 在线a视频网站| 精品国产乱码久久久久久1区2区| 久久夜色精品亚洲| 亚洲剧场午夜在线观看| 精品国产亚洲一区二区三区在线| 激情另类小说区图片区视频区| 91超薄肉色丝袜交足高跟凉鞋| 日韩在线资源网| 亚洲国产aⅴ精品一区二区三区| 校园激情久久| 国产在线观看黄色| 日韩123区| 一色屋成人免费精品网站| 国产精选在线观看91| 久久久久久久久影院| 91一区二区三区在线| 亚洲av无码片一区二区三区| 亚洲高清精品视频| 国产 中文 字幕 日韩 在线| 欧美成人精品一区二区三区在线看| 久久国产劲爆∧v内射| 一区二区三区亚洲变态调教大结局| 欧美男女交配| av免费在线一区| 不卡毛片在线看| 色88888久久久久久影院野外| 久久人人爽人人爽人人片av高请| 精品欧美一区二区三区免费观看| 日本三级日本三级日本三级极| 国产精品99蜜臀久久不卡二区| 国产精品无码久久久久| 成年人av网站| 成人性生交大片免费| 一级黄色片日本| av蜜臀在线|