• <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>

               C++ 技術中心

               :: 首頁 :: 聯系 ::  :: 管理
              160 Posts :: 0 Stories :: 87 Comments :: 0 Trackbacks

            公告

            鄭重聲明:本BLOG所發表的原創文章,作者保留一切權利。必須經過作者本人同意后方可轉載,并注名作者(天空)和出處(CppBlog.com)。作者Email:coder@luckcoder.com

            留言簿(27)

            搜索

            •  

            最新隨筆

            最新評論

            評論排行榜


            1.近來想研究tolua++,正好忙里抽閑,看些文章,并做了些總結。

            一.環境設置
            2.下載lua5.1  并安裝
            3.下載tolua++/Files/API/tolua-1.0.93.tar.bz2.zip  (下載完成后,把.zip去掉)
            4
            .新建工程lua++(生成靜態庫),將tolua++解壓后的tolua++-1.0.93\src\lib目錄下的6個.c和.h文件。加
               到該工程中。并設置附加包含目錄:
            C:\Program Files (x86)\Lua\5.1\include
                并編譯成功后,生成lua++.lib
            5.打開tolua-1.0.93\tolua++-1.0.93\win32\vc7目錄下的toluapp.sln,
              設置附加包含目錄:
            C:\Program Files (x86)\Lua\5.1\include 
              附加庫目錄:
            C:\Program Files (x86)\Lua\5.1\lib
              加入附加依賴項:lua5.1.lib
              最終生成到
            tolua-1.0.93\tolua++-1.0.93\bin\tolua++.exe

            二.測試一(變量訪問)
            1.新建工程NewLua
            2.Tarray.h如下:
            #ifndef _TARRAY_H__
            #define _TARRAY_H__

            extern int g_Arr[10];


            #endif/*_TARRAY_H__*/

            3.編寫pkg文件,內容如下:
            $#include "tarray.h"
            extern int g_Arr[10]@Arr;

            4.輸入命令:
            >tolua++.exe -n tarray -o tarray.cpp tarray.pkg
             -n tarray選項指定包的名字為tarray。如果不用-n顯式指定,tolua++.exe會生成一個和pkg文件名一樣的包名,同時生成tolua_**_open(lua_State*)入口函數。

            5.將生成的tarray.cpp加入到該工程中。并且加入lua5.1.lib,
            lua++.lib
              并附加包含lua的頭文件目錄

            6.在main文件如下:
            #include "stdafx.h"
            #include "lua.hpp"  
            #include "tarray.h"  

            int tolua_tarray_open (lua_State* tolua_S);  
            int g_Arr[10]={0};  

            int _tmain(int argc, _TCHAR* argv[])
            {
                lua_State * L = lua_open();  
                int i=0;  
                for(i=0; i<10; i++) g_Arr[i] = i;  

                luaopen_base(L);  
                tolua_tarray_open(L);  
                luaL_dofile(L, "C:/Users/Administrator/Desktop/test/NewLua/NewLua/array.lua");  

                printf("now in c++, re-show Arr:");  
                for(i=0; i<10; i++) printf("%d ", g_Arr[i]);  
                printf(" ");  

                lua_close(L);  
                return 0;
            }

            7.新建array.lua文件如下:
            print("now in lua script!   try to print 'Arr' by name:")
            print(Arr)
            print("now print 'Arr':")
            --print contents of Arr
            for i=0,9 do print(Arr[i]) end


            --change contents of Arr
            print("now change the Arr.")
            for i=0,9 do Arr[i] = i*2 end

            8.打印結果如下:
            now in lua script!   try to print 'Arr' by name:
            table: 008168E0
            now print 'Arr':
            0
            1
            2
            3
            4
            5
            6
            7
            8
            9
            now change the Arr.
            now in c++, re-show Arr:0 2 4 6 8 10 12 14 16 18

            二. 導出類
            1.同樣,新建
            tclass.h文件,內容如下:
            #ifndef _TESTCLASS_H  
            #define _TESTCLASS_H  
            #include "stdafx.h"
            #include <string.h>  

            class CNumber {   
                //tolua_export 
            public:   
                //tolua_begin      
                CNumber():m_nNum(0){ }      
                CNumber(int num):m_nNum(num){ }    
                ~CNumber() { }      
                void SetNumber(int num) { m_nNum = num; }     
                int GetNumber()     { return m_nNum; }     
                int Add(int num)  
                {             
                    m_nNum += num;          
                    return m_nNum;      
                }   
                
                //tolua_end  
            protected:  

                int m_nNum;  
            };   

            class CMessage
            {
            public:
                CMessage()
                {
                    strcpy(m_buff,"init message!");
                }
                ~CMessage()
                {

                }
                void SetMessage(char *msg)
                {
                    strcpy(m_buff,msg);
                }

                char *GetMessage()
                {
                    return m_buff;
                }

                void ShowMessage()
                {
                    printf("%s\n",m_buff);
                }
            protected:
                char m_buff[256];
            };

            //tolua_export  //tolua_begin  class

            #endif

            2.pkg文件內容如下:

            $#include "tclass.h"
            $#include "tarray.h"
            extern int g_Arr[10]@Arr;


            class CNumber {
            public:
                CNumber(); 
                CNumber(int num);
                ~CNumber();   
                void SetNumber(int num);    
                int GetNumber();    
                int Add(int num);
            };

            class CMessage
            {
            public:
                CMessage();
                ~CMessage();
                void SetMessage(char *msg);
                char *GetMessage();
                void ShowMessage();

            };

            3. 在導出類的時候,構造函數被映射到lua中的new,析構函數被映射為delete。接下來,用tolua++.exe生成用于完成“導出類到lua"功能的cpp文件。如下:
            tolua++.exe -n tarray -o tarray.cpp tarray.pkg

            4.main.cpp代碼如下:
            #include "stdafx.h"
            #include "lua.hpp"  
            #include "tarray.h"  

            int tolua_tarray_open (lua_State* tolua_S);  
            int g_Arr[10]={0};  

            int _tmain(int argc, _TCHAR* argv[])
            {
                lua_State * L = lua_open();  
                int i=0;  
                for(i=0; i<10; i++) g_Arr[i] = i;  

                luaopen_base(L);  
                tolua_tarray_open(L);  
                luaL_dofile(L, "C:/Users/Administrator/Desktop/test/NewLua/NewLua/array.lua");  
                
                
                printf("now in c++, re-show Arr:");  
                for(i=0; i<10; i++) printf("%d ", g_Arr[i]);  
                printf(" \n\n"); 

                
                luaL_dofile(L, "C:/Users/Administrator/Desktop/test/NewLua/NewLua/classtest.lua");  
                
                lua_close(L);  
                return 0;
            }

            4.新建
            classtest.lua文件內容如下:
            print("now in classtest.lua")


            --new a CNumber Object
            print("now allocate a CNumer object:")
            num = CNumber:new()
            num2=CNumber:new(222)
            print("init,num:"..num:GetNumber())
            print("init,num2:"..num2:GetNumber())



            -- set number
            print("now call SetNumber()")
            num:SetNumber(6)
            print("set number:"..num:GetNumber())

            -- delete object
            num:delete()
            print("num is deleted,access GetNumber is invalid!")
            print("invalidcall,result:"..num:GetNumber())

            -- new a CMessage Object
            msg=CMessage:new()
            print("init msg:"..msg:GetMessage())

            -- set message
            print("msg:SetMessage('changed message')")
            msg:SetMessage("changed message")
            print("now msg:"..msg:GetMessage())
            msg:ShowMessage()
            msg:delete()

            5.執行結果如下:
            now in lua script!   try to print 'Arr' by name:
            table: 00157D48
            now print 'Arr':
            0
            1
            2
            3
            4
            5
            6
            7
            8
            9
            now change the Arr.
            now in classtest.lua
            now in c++, re-show Arr:0 2 4 6 8 10 12 14 16 18

            now in classtest.lua
            now allocate a CNumer object:
            init,num:0
            init,num2:222
            now call SetNumber()
            set number:6
            num is deleted,access GetNumber is invalid!
            invalidcall,result:-17891602
            init msg:init message!
            msg:SetMessage('changed message')
            now msg:changed message
            changed message

            三. 導出聚合類
            1. 
            聚合是最常見的構造新類的方式了,另一個是繼承。tolua++支持單繼承,后面會提到繼承的例子。這里先看看怎么將利用了聚合的類導出到lua中。
               我的目的是想在Lua中使用C++類的實例,而不是在lua中生成C++類實例,所以我在利用tolua++向lua導出類時一般不導出構造函數,這樣就無法
              在lua中生成類實例。     但是為了演示的方便,這個例子中用到的兩個簡單類CNumber和CMessage仍然導出了構造函數。    

               另外一個單件(singleton)CTestSystem的構造函數、拷貝構造函數、=操作符都被聲明為protected,在向lua導出時只導出了 幾個方法。你無法
            在lua中生成它的實例,即便在C++中也不行,只能通過其靜態成員函數GetSingleton()獲取。

            2. 新建classg.h如下:
            #ifndef _CLASS_G_H__
            #define _CLASS_G_H__

            #include <string.h>

            class CNumberEx
            {
            public:
                CNumberEx():m_nNum(0){}
                CNumberEx(int num):m_nNum(num){}
                ~CNumberEx(){}

                void SetNumber(int num)    {m_nNum = num;}
                int GetNumber(){return m_nNum;}
                int Add(int num){m_nNum += num;return m_nNum;}
            protected:
                int m_nNum;
            };

            class CMessageEx{
            public:
                CMessageEx(){strcpy(m_szMessage,"init message");}
                CMessageEx(char *initMsg){if(initMsg) strcpy(m_szMessage,initMsg);}
                ~CMessageEx(){}
                void SetMessage(char *initMsg){if(initMsg) strcpy(m_szMessage,initMsg);}
                char *GetMessage(){return m_szMessage;}
                void ShowMessage(){printf("msg:%s\n",m_szMessage);}

            protected:
                char m_szMessage[256];
            };

            class CTestSystem
            {
            public:
                static CTestSystem &GetSingleton(){
                    static CTestSystem sys;
                    return sys;
                }

                
                CNumberEx& GetNumberObj(){return m_number;}
                CMessageEx & GetMessageObj(){return m_message;}
            protected:
                CTestSystem(){}
                CTestSystem(const CTestSystem &){}
                ~CTestSystem(){}
                CTestSystem& operator=(const CTestSystem &rhs);

            private:
                CNumberEx m_number;
                CMessageEx m_message;
            };

            #endif/*_CLASS_G_H__*/

            3.在tarray.pkg如下

            $#include "tclass.h"
            $#include "tarray.h"
            $#include "classg.h"

            extern int g_Arr[10]@Arr;


            class CNumber {
            public:
                CNumber(); 
                CNumber(int num);
                ~CNumber();   
                void SetNumber(int num);    
                int GetNumber();    
                int Add(int num);
            };

            class CMessage
            {
            public:
                CMessage();
                ~CMessage();
                void SetMessage(char *msg);
                char *GetMessage();
                void ShowMessage();

            };



            class CNumberEx
            {
            public:
                CNumberEx();
                CNumberEx(int num);
                ~CNumberEx();

                void SetNumber(int num);
                int GetNumber();
                int Add(int num);
            };

            class CMessageEx
            {
            public:
                CMessageEx();
                CMessageEx(char *initMsg);
                ~CMessageEx();
                void SetMessage(char *initMsg);
                char *GetMessage();
                void ShowMessage();
            };


            class CTestSystem
            {
            public:
                static CTestSystem &GetSingleton();
                CNumberEx& GetNumberObj();
                CMessageEx & GetMessageObj();
            };


            4.main如下:
            #include "stdafx.h"
            #include "lua.hpp"  
            #include "classg.h"
            #include "tarray.h"  



            int tolua_tarray_open (lua_State* tolua_S);  
            int g_Arr[10]={0};  

            int _tmain(int argc, _TCHAR* argv[])
            {
                
                
                /*
                在lua5.1中,用來生成lua狀態對象的lua_open函數不再直接可用,替換為lua_newstate,
                不過 lua_newstate要提供內存分配函數,lua擴展庫提供了無參數的luaL_newstate,
                用起來方便。同時為了向前兼容,還做了宏定 義#define lua_open luaL_newstate()。
                所以你仍然可以用lua_open來或者lua_State,但是要注意這里只是個宏。
                
                luaopen_base()打開基本的庫。     
                tolua_classgroup_open是tolua++生成的函數,用來向lua導出你定義的類和其它變量及函數。     
                luaL_dofile也是宏定義,用來加載并執行一個腳本文件,在lauxlib.h中定義。     
                lua_close關閉之前打開的狀態塊。
                
            */
                lua_State *L = luaL_newstate();
                luaopen_base(L);
                tolua_tarray_open(L);

                luaL_dofile(L, "C:/Users/Administrator/Desktop/test/NewLua/NewLua/classgroup.lua");  
                
                lua_close(L);  
                return 0;
            }

            5.同樣執行命令(注意生成的tarray.cpp加入到工程編譯)
            >tolua++.exe -n tarray -o tarray.cpp tarray.pkg

            6.lua腳本如下:
            print("now in classgroup.lua!")
            singleton = CTestSystem:GetSingleton()
            print(singleton)
            numobj = singleton:GetNumberObj()
            print(numobj)
            msgobj=singleton:GetMessageObj()
            print(msgobj)

            --access CNumber and CMessage
            print("init obj's number:"..numobj:GetNumber())
            numobj:SetNumber(100)
            print("after call numobj:SetNumber(100),number:"..numobj:GetNumber())
            print("init msgobj's message:"..msgobj:GetMessage())
            msgobj:SetMessage("This is message is set in lua script")
            print("new msg:"..msgobj:GetMessage())
            msgobj:ShowMessage()

            7.結果如下:
            now in classgroup.lua!
            userdata: 001C54D8
            userdata: 001CD388
            userdata: 001CD470
            init obj's number:0
            after call numobj:SetNumber(100),number:100
            init msgobj's message:init message
            new msg:This is message is set in lua script
            msg:This is message is set in lua script


            三. 導出單繼承類
            1. 新建inheritance.h文件如下:
            #ifndef _INHERITANCE_H__
            #define _INHERITANCE_H__

            #include <Windows.h>
            #include <string>

            typedef enum{
                AUICSNormal   = 0,
                AUICSHover    = 1,
                AUICSPushed   = 2,
                AUICSDisabled = 3,
                AUICSHide     = 4,
                AUICSFORCEDOWRD = 0xFFFFFFFF
            }AUIControlState;


            class CAUIControl
            {
            public:
                CAUIControl():m_nID(-1),m_state(AUICSNormal),m_bEnable(true),m_strText(""){}
                virtual ~CAUIControl(){}

            public:
                void SetID(int nID){m_nID = nID;}
                int GetID(){return m_nID;}
                
                void SetText(char *szText){m_strText = szText;}
                const char* GetText(){return m_strText.c_str();}

                void SetSize(SIZE sz){m_size = sz;}
                SIZE GetSize(){return m_size;}

                void SetEnabled(bool bEnable){m_bEnable = bEnable;}
                bool IsEnabled(){return m_bEnable;}

                void SetPosition(POINT pt){m_position = pt;}
                POINT GetPosition(){return m_position;}

            public:
                virtual void Render() = 0;

                virtual bool MsgProc(HWND hwnd,UINT uMsg,WPARAM wPram,LPARAM lParam){return false;}

            protected:
                int m_nID;
                POINT m_position;
                AUIControlState m_state;
                std::string m_strText;
                SIZE m_size;
                bool m_bEnable;
            };

            class CAUIButton : public CAUIControl
            {
            public:
                CAUIButton():m_pTexture(NULL){}
                virtual ~CAUIButton(){}

            public:
                void SetTexture(char *szFile){}
                void SetTextureRects(const RECT &rcNormal,const RECT &rcHover,const RECT &rcPushed,const RECT &rcDisabled){}

            public:
                void Render(){printf("CAUIButton::Render");}
                 bool MsgProc(HWND hwnd,UINT uMsg,WPARAM wPram,LPARAM lParam)
                 {
                    
                     printf("CAUIButton::MsgProc ");
                     return false;
                 }
            protected:
                void *LoadTexture(char *szTextureFile){return NULL;}
                void *m_pTexture;
                RECT m_rects[4];
            };

            extern CAUIButton g_button;


            #endif/*_INHERITANCE_H__*/

            2.pkg文件如下:
            $#include "inheritance.h"

            class CAUIControl
            {
            public:
                void SetID(int nID);
                int GetID();
                
                void SetText(char *szText);
                const char* GetText();

                void SetSize(SIZE sz);
                SIZE GetSize();

                void SetEnabled(bool bEnable);
                bool IsEnabled();

                void SetPosition(POINT pt);
                POINT GetPosition();
            };

            class CAUIButton : public CAUIControl
            {
            public:
                CAUIButton();
                virtual ~CAUIButton();

            public:
                void SetTexture(char *szFile);
                void SetTextureRects(const RECT &rcNormal,const RECT &rcHover,const RECT &rcPushed,const RECT &rcDisabled);
            };

            extern CAUIButton g_button@button;

            3.main文件如下:

            CAUIButton g_button;
            int _tmain(int argc, _TCHAR* argv[])
            {
                lua_State *L = luaL_newstate();
                luaopen_base(L);
                tolua_tarray_open(L);
                
                //luaL_dofile(L, "C:/Users/Administrator/Desktop/test/NewLua/NewLua/classgroup.lua");  
                luaL_dofile(L, "C:/Users/Administrator/Desktop/test/NewLua/NewLua/inheritance.lua");  
                
                lua_close(L);  
                return 0;
            }


            4. lua腳本如下:
            print("now in inheritance.lua!")
            -- access global
            button:SetID(100)
            button:SetText("global button")
            print(button:GetText())

            newbutton = CAUIButton:new()

            newbutton:SetID(100)
            newbutton:SetText("new button")
            print(newbutton:GetText())


            5.輸出結果:
            now in inheritance.lua!
            global button
            new button


            四.互調綜合實例

            1. 新建toluaclass.h如下:
            #ifndef _TOLUACLASS_H_
            #define _TOLUACLASS_H_

            class CBase
            {
            public:
                CBase(){}
                virtual ~CBase(){}

                virtual void ShowMessage(){printf("BaseClass\n");}
                static char *ClassName(){return "CBase\n";}
            };

            class CDerived1 : public CBase{
            public:
                CDerived1(){}
                ~CDerived1(){}

                void ShowMessage(){printf("CDerived1Class\n");}
                void ShowDerived1(){printf("show derived1\n");}
            };


            class CDerived2:public CBase{
            public:
                CDerived2(){m_nNumber = 0;}
                ~CDerived2(){}
                
                void ShowMessage(){printf("Derived2Class\n");}
                void ShowDerived2(){printf("show derived2\n");}
                void SetNumber(int num){m_nNumber = num;}
                int GetNumber(){return m_nNumber;}

            protected:
                int m_nNumber;
            };

            extern CDerived1 * toDerived1(void *p);
            extern CDerived2 * toDerived2(void *p);

            #endif/*_TOLUACLASS_H_*/

            2.pkg文件如下:
            $#include "toluaclass.h"


            class CBase
            {
            public:
                virtual void ShowMessage();
                static char *ClassName();
            };

            class CDerived1 : public CBase{
            public:

                void ShowMessage();
                void ShowDerived1();
            };


            class CDerived2:public CBase{
            public:    
                void ShowMessage();
                void ShowDerived2();
                void SetNumber(int num);
                int GetNumber();
            };

            extern CDerived1 * toDerived1(void *p);
            extern CDerived2 * toDerived2(void *p);


            $[
            testHelper={}

            function testHelper.toDerived3(e)

              return tolua.cast(e,"CDerived2")
            end

            $]
            tolua++提供了轉換機制,tolua++生成了一些工具函數,在tolua為名的module中。其中tolua.cast就是用來做類型轉換的。只需要改動tlclass.pkg文件
            3. 驅動代碼如下:
            // NewLua.cpp : 定義控制臺應用程序的入口點。
            //

            #include "stdafx.h"
            #include "lua.hpp"  
            #include "classg.h"
            #include "tarray.h"  
            #include "inheritance.h"
            #include "toluaclass.h"


            int tolua_tarray_open (lua_State* tolua_S);  



            CDerived1 *toDerived1(void *p)
            {
                return dynamic_cast<CDerived1*>((CBase*)p);
            }

            CDerived2 *toDerived2(void *p)
            {
                return dynamic_cast<CDerived2*>((CBase*)p);
            }

            int _tmain(int argc, _TCHAR* argv[])
            {
                lua_State *L = luaL_newstate();
                luaopen_base(L);
                tolua_tarray_open(L);
                
                //luaL_dofile(L, "C:/Users/Administrator/Desktop/test/NewLua/NewLua/classgroup.lua");  
                luaL_dofile(L, "C:/Users/Administrator/Desktop/test/NewLua/NewLua/CallLuaFunc.lua");  
                
                CBase *p1 = new CDerived1();
                CBase *p2 = new CDerived2();

                //call Derived1Test
                lua_getglobal(L,"Derived1Test");
                lua_pushlightuserdata(L,p1);
                
                if(lua_pcall(L,1,0,0)!=0)
                {
                    fprintf(stderr,"Call Devied1Test failed:%s",lua_tostring(L,-1));
                }

                //call Derived2Test
                lua_getglobal(L,"Derived2Test");
                lua_pushlightuserdata(L,p2);
                if(lua_pcall(L,1,0,0)!=0)
                {
                    fprintf(stderr,"Derived2Test failed:%s",lua_tostring(L,-1));
                }

                //lua中轉換測試
                lua_getglobal(L,"Derived3Test");
                lua_pushlightuserdata(L,p2);
                if(lua_pcall(L,1,0,0)!=0)
                {
                    fprintf(stderr,"Derived3Test failed:%s",lua_tostring(L,-1));
                }


                delete p1;
                delete p2;

                lua_close(L);  
                return 0;
            }

            在C++中調用lua腳本的函數大概分為三步:    
            a..找到函數并入棧;(這里是lua_getglobal(L,  "Derived1Test");)    
            b..參數入棧;(這里是lua_pushlightuserdata(L, p1);)    
            c..調用lua_pcall進行實際調用    
            第一步不必說了;
            第二步可以傳遞任意個任意類型的參數,lua_pushnumber,lua_pushstring, lua_pushboolean等 等可以調用;
            第三步是調用lua_pcall,lua_pcall第一個參數是lua_State*,
            這是我們的工作環境了。
            第二參數是要傳遞的參數個 數,我們這里是1;
            第三個參數是lua函數返回的結果個數,我們的lua函數不返回結果,設為0。
            第四個參數是比較復雜,為0時指lua_pcall會在 調用失敗時把原始錯誤信息放到棧上;
            其它值代表棧的索引,該索引處放了一個錯誤處理函數,lua_pcall失敗時會根據這個索引去調用該函數。     調用失敗的時候我只是簡單地打印一條出錯信息,這個錯誤碼放在棧頂,我們用lua_tostring(L,-1)訪問并轉換為字符串。可以修改下驅動代 碼,比如把第二次調用傳入p1,這樣就可以看見錯誤信息。     最后我還是在C++代碼中打印了下CDerived2對象的值,以驗證lua和C++中訪問的是同一個對象。    Lua和C++的交互都是通過棧,所以要寫交互部分的代碼就要不停的出棧入棧,煩死個人。不過這也是Lua靈活的地方。
            4.lua腳本如下:
            print ("now in CallLuaFunc.lua!")

            -- lua function to test CDerived1, CDerived2, they'll be called from C++

            function Derived1Test(e)

            d1 = toDerived1(e)
            if d1 then
                d1:ShowMessage()
                d1:ShowDerived1()

            else
                print("invalid d1(nil)")

            end

            end


            function Derived2Test(e)

            d2 = toDerived2(e)

            if d2 then
                d2:ShowMessage();
                d2:ShowDerived2();
                d2:SetNumber(180);

                print(d2:GetNumber())


            else
                print("invalid d2(nil)")

            end

            end



            -- 利用pkg中的tolua.cast轉換
            function Derived3Test(e)
            d3 = testHelper.toDerived3(e)

            if d3 then
                d3:ShowMessage();
                d3:ShowDerived2();
                d3:SetNumber(380);

                print(d3:GetNumber())


            else
                print("invalid d3(nil)")

            end

            end


            posted on 2014-05-07 14:06 C++技術中心 閱讀(5598) 評論(0)  編輯 收藏 引用 所屬分類: 游戲開發
            97精品依人久久久大香线蕉97 | 久久国产精品成人片免费| 国内精品人妻无码久久久影院导航 | 久久乐国产精品亚洲综合| 久久久WWW成人| 亚洲精品成人久久久| jizzjizz国产精品久久| 国产精品一区二区久久精品| 久久精品视频91| 日产精品久久久久久久| 久久精品国产色蜜蜜麻豆| 久久久久亚洲AV片无码下载蜜桃| 性做久久久久久久| 麻豆精品久久精品色综合| 久久精品国产AV一区二区三区 | 久久久久一本毛久久久| 国产精品美女久久福利网站| av午夜福利一片免费看久久| 久久精品国产亚洲7777| 成人国内精品久久久久一区| 婷婷综合久久中文字幕| 一本色道久久综合亚洲精品| 精品无码久久久久久久动漫| 久久亚洲AV成人无码电影| 久久se这里只有精品| 精品国产福利久久久| 99久久香蕉国产线看观香| 66精品综合久久久久久久| 久久久久人妻一区二区三区vr| 中文字幕无码久久人妻| 精品国产一区二区三区久久蜜臀| 久久er99热精品一区二区| 久久热这里只有精品在线观看| 精品久久久久久国产牛牛app| 狠狠88综合久久久久综合网| 色婷婷久久综合中文久久一本 | 思思久久99热只有频精品66| 亚洲伊人久久大香线蕉苏妲己| 欧美亚洲国产精品久久蜜芽| 久久人爽人人爽人人片AV| 2021国产精品久久精品|