• <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++ 技術(shù)中心

               :: 首頁 :: 聯(lián)系 ::  :: 管理
              160 Posts :: 0 Stories :: 87 Comments :: 0 Trackbacks

            公告

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

            留言簿(27)

            搜索

            •  

            最新隨筆

            最新評(píng)論

            評(píng)論排行榜

            關(guān)鍵字:
              and break do else elseif end false for function if in local nil not or repeat return then true until while
            使用變量不需要聲明,總是全局變量,除非加"local"。local的作用域是在最里層的end和其配對(duì)的關(guān)鍵字之間。全局變量的作用域是整個(gè)程序。大小寫相關(guān)。定義一個(gè)變量的方法就是賦值"="操作。變量類型,可以用type()函數(shù)來檢查:
              Nil  空值,所有沒有使用過的變量都是nil。nil既是值又是類型。變量清除直接給變量賦以nil值。
              Boolean  布爾值true 和 false。只有false和nil才被計(jì)算為false,而所有任何其它類型的值,都是true。比如0,空串等等,都是true。
              Number  數(shù)值,相當(dāng)于C語言的double實(shí)數(shù)如:4 0.4 4.57e-3 0.3e12 5e+20
              Userdata  可以是宿主的任意數(shù)據(jù)類型,常用的有Struct和指針。
              Thread 線程類型,在Lua中沒有真正的線程,將一個(gè)函數(shù)分成幾部份運(yùn)行。
              String  字符串,可以包含'/0'字符,可以定義很長(zhǎng)的字符串。用雙引號(hào)或單引號(hào)引用單行,"[["和"]]"引用多行字符串。新版支持"[==["和"]==]"多層標(biāo)記,=號(hào)個(gè)數(shù)為層數(shù)。嚴(yán)格按層數(shù)匹配。支持一些轉(zhuǎn)義字符:
            /a鈴/b退格/f換頁/n換行/r回車/t制表符/v垂直制表//反斜杠/"雙引號(hào)/'單引號(hào)/[左中括號(hào)/]右中括號(hào)
              Table  關(guān)系表類型,功能強(qiáng)大。可以用除了nil任意類型的值來作數(shù)組的索引和內(nèi)容。
              Table的定義:T1 = {}  T1[1]=10  T1["John"]={Age=27, Gender="Male"}
                這一句相當(dāng)于T1["John"]["Gender"]="Male"
                索引是字符串時(shí)可以簡(jiǎn)寫成:T1.John.Gender="Male"或T1.John={Age=27, Gender="Male"}
                第一,所有元素之間,總是用逗號(hào)","隔開;
                第二,所有索引值都需要用"["和"]"括起來;如果是字符串,還可以去掉引號(hào)和中括號(hào);
                第三,如果不寫索引,則索引就會(huì)被認(rèn)為是數(shù)字,并按順序自動(dòng)從1往后編;
                T1=
                {
                  10,  -- 相當(dāng)于 [1] = 10
                  [100] = 40,
                  John=  -- 如果你原意,你還可以寫成:["John"] =
                  {
                    Age=27,   -- 如果你原意,你還可以寫成:["Age"] =27
                    Gender=Male   -- 如果你原意,你還可以寫成:["Gender"] ="Male"
                  },
                  20  -- 相當(dāng)于 [2] = 20
                }
              Function  函數(shù)也是一種類型,也就是說所有的函數(shù)本身就是一個(gè)變量。
            函數(shù)的定義:function add(a,b) return a+b end 相當(dāng)于add = function (a,b) return a+b end
            如果函數(shù)只有一個(gè)參數(shù),可以省略括號(hào)。
            return語言一定要寫在end之前。在中間放上return,寫成:do return end。
            函數(shù)可以接受可變參數(shù)個(gè)數(shù),用"..."來定義function sum (a,b,...)
            如 果想取得...所代表的參數(shù),5.0版本可以在函數(shù)中訪問arg局部變量(表類型)得到。如 sum(1,2,3,4)則,a = 1, b = 2, arg = {3, 4},在5.1版本多了一個(gè)...變量(實(shí)際就是參數(shù)列表),區(qū)別只在于arg和...共同存在的情況,...會(huì)使arg變nil。
            可以同時(shí)返回多個(gè)結(jié)果,比如:function s() return 1,2,3,4 end
                a,b,c,d = s()  -- 此時(shí),a = 1, b = 2, c = 3, d = 4
            使用面向?qū)ο缶幊蹋?br />    t = { Age = 27, add = function(self, n) self.Age = self.Age+n end }
                print(t.Age)  -- 27
                t.add(t, 10) 可以簡(jiǎn)寫成:t:add(10)
                print(t.Age)  -- 37

            單行注釋"--"。只要--后面第一個(gè)字符不是多行字符串引用符[[,即為多行注釋。
            語句之間可以用分號(hào)";"隔開,也可以用空白隔開。
            條件控制:if 條件 then … elseif 條件 then … else … end
            While循環(huán):while 條件 do … end
            Repeat循環(huán):repeat … until 條件
            For循環(huán):for 變量 = 初值,終點(diǎn)值,步進(jìn) do … end
            可以省略步進(jìn)值,這時(shí)候,for循環(huán)會(huì)使用1作為步進(jìn)值。
            For循環(huán):for 變量1,變量2,… ,變量N in表或枚舉函數(shù) do … end
            語句塊用do 和 end 括起來的。可以在函數(shù)中和語句塊中定局部變量。
            賦值語句可以同時(shí)給多個(gè)變量賦值。例如:a,b,c,d=1,2,3,4甚至是:a,b=b,a 方便的交換變量功能
            默認(rèn)變量總是全局的。定義局部變量,則在第一次賦值的時(shí)候用local說明。比如:
              local a,b,c = 1,2,3  -- a,b,c都是局部變量
            數(shù)值運(yùn)算支持 +, -, *, /,^,#,%。^表示指數(shù)乘方。比如2^3 結(jié)果為8。5.1版加了#長(zhǎng)度運(yùn)算符。字符串的長(zhǎng)度單位為字節(jié),表的長(zhǎng)度為nil前的整數(shù)索引個(gè)數(shù),也就是數(shù)組的個(gè)數(shù),如果有名為n的索引,它的值就是長(zhǎng)度。5.1版引進(jìn)%模運(yùn)算。
            用".."連接兩個(gè)字符串。如:"This a " .. "string." -- 等于 "this a string"
            比較運(yùn)算< > <= >= == ~=分別表示 小于,大于,不大于,不小于,相等,不相等。總是返回true或false。對(duì)于Table,F(xiàn)unction和Userdata類型的數(shù)據(jù),只有 == 和 ~=可以用。相等表示兩個(gè)變量引用的是同一個(gè)數(shù)據(jù)。比如: a={1,2}    b=a    print(a==b, a~=b)  -- true, false
                a={1,2}    b={1,2}    print(a==b, a~=b)  -- false, true
            邏輯運(yùn)算and, or, not只有false和nil才計(jì)算為false,其它任何數(shù)據(jù)都計(jì)算為true,0也是true!
                and 和 or的運(yùn)算結(jié)果不是true和false,而是和它的兩個(gè)操作數(shù)相關(guān)。
                a and b:如果a為false,則返回a;否則返回b
                a or b:如果 a 為true,則返回a;否則返回b
            運(yùn)算符優(yōu)先級(jí),從高到低順序如下:
                ^
                not - (一元運(yùn)算)#
                 * / %
                 + -
                 ..(字符串連接)
                 < > <= >= ~= ==
                 and
                 or
                 =
            常用標(biāo)準(zhǔn)庫(kù)函數(shù):
            print (···)把所有參數(shù)打印出來,利用tostring (e)轉(zhuǎn)換非字符。奇怪的是nil不能做..操作。
            table.insert (table, [pos,] value)在pos位置插入一個(gè)值,默認(rèn)是末尾。
            table.remove (table [, pos])在pos位置刪除一個(gè)值,默認(rèn)是末尾。
            table.concat (table [, sep [, i [, j]]])用sep來連接數(shù)組里從i到j(luò)字符串或數(shù)字并返回一個(gè)長(zhǎng)字符串,默認(rèn)用空串從1到末尾。如果j大于i,返回空串。
            table.maxn (table)返回最大正數(shù)索引或0。
            table.sort (table [, comp])對(duì)數(shù)組排序,排序函數(shù)默認(rèn)是<。
            string.byte (s [, i [, j]])返回s串從i到j(luò)的數(shù)值。舊版只支持2個(gè)參數(shù)
            string.char (···)和byte函數(shù)功能相反,返回0或多個(gè)數(shù)字對(duì)應(yīng)的字符串。
            string.find (s, pattern [, init [, plain]])從s串中從init位置開始找到第一個(gè)匹配模式的子串位置,并返回起點(diǎn)和終點(diǎn)。plain如果為true,忽略模式。如果使用了捕獲,則增加返回捕獲的部分。
            string.gmatch (s, pattern)這是一個(gè)迭代函數(shù),每次返回一個(gè)匹配的串。舊版叫g(shù)find。如果使用了捕獲,則返回捕獲的部分。
            string.gsub (s, pattern, repl [, n])用rep1替換。n限制替換個(gè)數(shù)。%1-9表示被捕獲的值。如果第3個(gè)參數(shù)是個(gè)函數(shù)并返回假,替換字符將保持原配而不是舊版的空串。
            string.sub (s, i [, j])返回s從位置i到j(luò)的子串。負(fù)值表示從末尾往前數(shù)的位置。默認(rèn)從1到末尾。
            string.match (s, pattern [, init])從init匹配或捕獲值返回。舊版沒有這個(gè)函數(shù)。
            string.format (formatstring, ···)格式化輸出。%q可以輸出安全字符串。
            string.rep (s, n)把s復(fù)制n份
            string.reverse (s)把s倒轉(zhuǎn)。舊版沒有這個(gè)函數(shù)。
            string.len (s)計(jì)算字符串長(zhǎng)度。
            string.lower (s)小寫化。string.upper (s)大寫化。
            io.read (···)"*n"讀一個(gè)數(shù)字,支持各種格式;"*a"讀整個(gè)文件;"*l":讀一行,默認(rèn);"n"讀n個(gè)字符
            io.write (···)寫字符或者數(shù)字
            io.lines ([filename])迭代返回文件中的一行。
            pairs (t)迭代返回表中的鍵值對(duì)
            ipairs (t)迭代返回?cái)?shù)組中的索引和值
            module (name [, ···])創(chuàng)建一個(gè)模塊。require (modname)加載一個(gè)模塊
            模式表:
            .任意字符%w字母和數(shù)字%a字母%d數(shù)字%p標(biāo)點(diǎn)字符%s空白符%大寫字母表示相應(yīng)集合的補(bǔ)集
            %u大寫字母%l小寫字母%x十六進(jìn)制數(shù)字%z代表0的字符%c控制字符
            %是轉(zhuǎn)義標(biāo)識(shí) []集合 ^補(bǔ)集
            ()表示捕獲 %1-9是捕獲值 %bxy是以xy為標(biāo)識(shí)的對(duì)稱結(jié)構(gòu)
            ?匹配前一字符0次或1次 +匹配前一字符1次或多次
            *最長(zhǎng)匹配前一字符0次或多次 -最短匹配前一字符0次或多次
            以^開頭的模式只匹配目標(biāo)串的開始部分,相似的,以$結(jié)尾的模式只匹配目標(biāo)串的結(jié)尾部分。
            c調(diào)用lua函數(shù)一般的過程是:
            1. load一個(gè)lua的文件,形成一個(gè)閉包并執(zhí)行它
            2. 在棧中壓入函數(shù)的名稱
            3. 依次在棧中壓入函數(shù)的實(shí)參
            4. 使用lua_pcall調(diào)用lua函數(shù)。 形式是: lua_pcall(L, 參數(shù)個(gè)數(shù),結(jié)果個(gè)數(shù), 錯(cuò)誤處理函數(shù)在棧中的索引)
                此時(shí)此函數(shù)相關(guān)的棧已經(jīng)被清空。執(zhí)行l(wèi)ua完畢后,如果成功,結(jié)果依次將壓入棧中, 如果不成功,錯(cuò)誤信息將 壓入棧中
            5. 從棧中讀取返回結(jié)果或者錯(cuò)誤信息。
            lua調(diào)用c函數(shù)(寫成庫(kù)的例子)
            lua調(diào)用庫(kù)在windows下是dll文件,在unix/linux下面是so文件
            vs的過程如下:
            1. 新建一個(gè)dll的工程
            2. 定義一個(gè)def文件,定義dll的導(dǎo)出,mylib.def定義如下:
            LIBRARY  mylib.dll
            DESCRIPTION "first dll for lua"
            EXPORTS
            luaopen_mylib
            3. 編寫庫(kù),新建一個(gè)cpp文件.
            4. 定義庫(kù)函數(shù),這里以pil的lsin函數(shù),輸出傳入?yún)?shù)的sin()值
            5. 定義luaL_reg數(shù)組,這個(gè)是注冊(cè)一系列公開給lua調(diào)用的函數(shù)數(shù)組. 數(shù)組最后一個(gè)元素必須是 {NULL, NULL} 的luaL_reg結(jié)構(gòu)用來做結(jié)束標(biāo)識(shí).
            6. 用luaL_openlib聲明主函數(shù)
            5.1版本和5.0版本的區(qū)別:
            新模塊系統(tǒng),增量垃圾收集,varargs新機(jī)制,多行字符串或引用的新語法,#和%新操作符, metatable支持所有類型,使用luaconf.h來配置lua暫時(shí)避免版本沖突,完善的reentrant parser。Pil第二版包括了5.1的新內(nèi)容,增加了新例子,對(duì)新模塊系統(tǒng),多狀態(tài)和垃圾收集的詳細(xì)闡述。
            語法:
            函數(shù)傳遞可變參數(shù)用...來代替局部arg表。不使用...時(shí),arg用法和舊版本一樣;但使用...后(無論先后),局部arg都會(huì)變成nil。
            在repeat.until里,局部變量的生命周期覆蓋到until條件后面;
            多行字符串或引用的新語法使用多層匹配代替以前的嵌套;
            #和%新操作符。
            庫(kù)函數(shù):
            string.gfind改為string.gmatch;
            如果調(diào)用string.gsub的第3個(gè)參數(shù)是個(gè)函數(shù),如果函數(shù)返回假,替換字符將保持原配而不是舊版的空串;
            table.setn廢棄,table.getn改為使用#;
            loadlib改為package.loadlib;
            math.mod改為math.fmod;
            table.foreach和table.foreachi作廢。可用for循環(huán)pairs或ipairs代替;
            require從package.path而不是LUA_PATH得到path值;
            collectgarbage (opt [, arg])參數(shù)從[limit]改為更多選擇,gcinfo廢棄改為collectgarbage("count");
            string.byte (s [, i [, j]])返回s串從i到j(luò)的數(shù)值。舊版只支持2個(gè)參數(shù)
            string.match (s, pattern [, init])從init匹配或捕獲值返回。舊版沒有這個(gè)函數(shù)。
            string.reverse (s)把s倒轉(zhuǎn)。舊版沒有這個(gè)函數(shù)。
            module (name [, ···])創(chuàng)建一個(gè)模塊。舊版沒有這個(gè)函數(shù)。
            C API:
            5.1版本增加了以luaL_開頭的輔助庫(kù)Auxiliary Library;
            luaL_getn改為lua_objlen,luaL_setn廢棄;
            luaL_openlib改為luaL_register;
            luaL_checkudata改為拋出異常而不是返回NULL。
            luaopen_* functions不能直接調(diào)用,改為像調(diào)用其它普通c函數(shù)一樣的過程;
            lua_open改為lua_newstate,可以設(shè)置內(nèi)存分配方法。luaL_newstate默認(rèn)使用realloc分配方法;
            5.0的調(diào)用方法:
             lua_State *L = lua_open();
             luaopen_base(L);
             luaopen_string(L);
             luaopen_math(L);
            5.1的調(diào)用方法:
             lua_State *L = luaL_newstate();
             lua_cpcall(L, luaopen_base, 0);
             lua_cpcall(L, luaopen_io, 0);
             lua_cpcall(L, luaopen_math, 0);
             lua_cpcall(L, luaopen_string, 0);
            lua_pushcfunction(L, luaopen_*);lua_call();等價(jià)于lua_cpcall(L, luaopen_*, 0);
             
            其他經(jīng)驗(yàn):
            lua的擴(kuò)展庫(kù)luasocket, luasql, luacom, kepler...
            程序可以存成cpp也可以存成c, 如果以.c為擴(kuò)展名就不需要加extern "C"
            c和lua交互的時(shí)候,棧的編號(hào)是從1-n,也可以取負(fù)值,-1表示末尾
            設(shè)置環(huán)境變量LUA_PATH="E:/LuaEdit/myproject/?.lua",然后使用require "lua包/文件名"。然后就可以直接使用lua文件里的函數(shù)而不需要dofile(路徑)了。在windows下的路徑如果是/必須寫成//,或者/。
            lua5.1win32的解析器下載來后可以直接使用。luasocketwin32擴(kuò)展包下載后,需要正確設(shè)置LUA_PATH=< LDIR>/?.lua;?.lua和LUA_CPATH=<CDIR>/?.dll;?.dll。然后運(yùn)行l(wèi)ua解析器, require相應(yīng)的socket包就可以了。
            在VC++6下編譯帶lua的.dll文件的時(shí)候,在工程設(shè)置里必須指明LIBC.lib Libcmtd.lib的加載順序。選擇VC菜單Project->Settings->Link->Catagory然后在 Object/library  Modules的Edit欄中填入LIBC.lib Libcmtd.lib。否則會(huì)出現(xiàn):
            Linking...
            LIBC.lib(crt0dat.obj) : error LNK2005: __cinit already defined in LIBCMTD.lib(crt0dat.obj)
             
            新版本下表迭帶需要加pairs(t),舊版本以下代碼結(jié)果是正確的:
            Lua 5.1.2  Copyright (C) 1994-2007 Lua.org, PUC-Rio
            > function print_contents(t)
            >> for k,v in t do
            >> print(k .. "=" .. v)
            >> end
            >> end
            > print_contents{x=10, y=20}
            stdin:2: attempt to call a table value
            stack traceback:
                    stdin:2: in function 'print_contents'
                    stdin:1: in main chunk
                    [C]: ?
             
            新版本中的...和arg不能同時(shí)出現(xiàn),無論先后,...的出現(xiàn)都會(huì)使arg為nil:
            print(#arg)
            function test(...)
            --print(...)
            print(type(arg),#arg)
            --print(...)
            end
            test(1,2,3,4)
            print(#arg)
            運(yùn)行結(jié)果:
            E:/lua5_1_2_Win32_bin>lua5.1 e....lua 1 2 3
            3
            table   4
            3
            結(jié)果說明arg在新版本中還是可以使用的,但跟...沖突,跟全局表arg不沖突。但本地arg會(huì)覆蓋全局的arg,如果兩者都要調(diào)用該如何處理?使用...后,編譯器仍然把函數(shù)里的arg看成是局部變量。因此變通的方法是:
            print(#arg)
            t=arg
            function test(...)
            print(...)
            arg=t
            print(type(arg),#arg)
            --print(...)
            end
            test(1,2,3,4)
            print(#arg)
            這和舊版本是一樣的。看來引入...的用意不是為了區(qū)分全局和局部的arg。那究竟是為了什么呢??
             
            lua安裝:
            Windows:  
            把etc目錄下的luavs.bat 拷到lua的解壓根目錄下直接運(yùn)行, 生成的.h .dll .lib .exe文件都在src下。
            Linux:
            $make linux && make install 標(biāo)準(zhǔn)的linux安裝

            在Windows XP SP2下使用Visual C++ 6. 編譯lua的過程分為3步:
            1,建立靜態(tài)庫(kù)工程,編譯庫(kù)文件
                 Lua庫(kù)由標(biāo)準(zhǔn)庫(kù)和核心庫(kù)組成,我用的是5.1版本,所有代碼都放在src目錄中。把src目錄中除lua.c,luac.c文件外所有的*.c文件添加到項(xiàng)目中,設(shè)置一下輸出路徑,F(xiàn)7編譯就可以了。
            2,建立Win32控制臺(tái)工程 編譯lua.exe Lua解釋器
               把lua.c添加到工程中,link選項(xiàng)中包含進(jìn)剛才編譯好的lib文件,F(xiàn)7編譯
            3.再建立Win32控制臺(tái)工程, 編譯luac.exe  Lua編譯器
               同上步一樣,編譯成功后生成luac.exe, 最好把這兩個(gè)文件放在新建的bin文件下,在添加進(jìn)系統(tǒng)的環(huán)境變量。 
             
            tolua++在cygwin下不用SCons編譯:
            詳見http://lua-users.org/wiki/CompilingToluappWithoutScons
            src/lib下:
            gcc -shared -o tolua++.dll *.c /usr/local/lib/lua51.dll -I../../include -I/usr/local/include
            gcc -c *.c  -I../../include -I/usr/local/include
            ar rcsv libtolua++.a *.o
            src/bin下:
            gcc tolua.c toluabind.c -I../../include -I/usr/local/include -L /usr/local/lib -llua -L../lib/ -ltolua++
            然后把所得到的文件復(fù)制到系統(tǒng)相應(yīng)目錄中。
            使用tolua用.pkg生成.cpp的時(shí)候,在生成的.cpp最前面設(shè)置#define TOLUA_API extern "C" __declspec(dllexport)可以使.dll文件導(dǎo)出時(shí)不改變文件名。貌似還要加
            #ifndef __cplusplus#define __cplusplus#endif
            使用cygwin產(chǎn)生的.dll文件不能被lua使用。用同一源文件在vc下生成的.dll文件是可以被lua用的。
            使用VC編譯tolua時(shí),把除了tolua.c和xxx.defalt以外的.c和.h都包含進(jìn)去,然后在tolua++.h里設(shè)置 #define TOLUA_API extern "C" __declspec,不斷得修改#include "tolua++.h"在各個(gè)文件中的位置,使得用dumpbin看到65個(gè)導(dǎo)出函數(shù)為止。貌似VC6版本太低不能成功設(shè)置預(yù)編譯處理選項(xiàng),因此這樣麻煩 點(diǎn)。編譯成功后就有.lib和.dll文件供接下來的.dll工程使用。

            extern "C" _declspec(dillexport)
            extern "C" void DLL_EXPORT __stdcall
             
            ============
            實(shí)際應(yīng)用場(chǎng)景練習(xí)
            ============
            一、利用Lua的Table實(shí)現(xiàn)類的多繼承:
                1、假設(shè)基類為B1、B2
                2、繼承的類為A
                3、使用的時(shí)候類似于:
                        Instance1 = A:new()
                        Instance1:Method1(arg1, arg2)
                這個(gè)不難,但是務(wù)必要掌握table的應(yīng)用
            答案:見OO.lua。在lua解析器下運(yùn)行:dofile "OO.lua"
             
            二、利用lua的擴(kuò)展包luasocket實(shí)現(xiàn)http的一個(gè)應(yīng)用:
                1、構(gòu)造http協(xié)議,訪問www.qq.com,具體的訪問方式網(wǎng)上有例子。
                2、在返回來的http包中,取出騰訊公司的客服電話號(hào)碼 -- 需要使用到lua的字符串查找和模式匹配函數(shù)。
            答案:
            下載lua5.1win32的解析器和luasocketwin32擴(kuò)展包,正確設(shè)置LUA_PATH=< LDIR>/?.lua;?.lua和LUA_CPATH=<CDIR>/?.dll;?.dll,<CDIR>指向 luasocket-2.0.1-lua5.1-win32/lib,<LDIR>指向luasocket-2.0.1-lua5.1- win32/lua。lua程序見Phone.lua。在lua解析器下運(yùn)行:dofile "Phone.lua"
            ----------------------------
            http = require("socket.http")
            qqweb = http.request("http://www.qq.com")
            tel=string.match(qqweb,"騰訊客服電話:(%d+%-%d+)")
            print("您要的電話號(hào)碼是:"..tel)
            -------------------------------

            三、在Windows下,利用C++實(shí)現(xiàn)一個(gè)基本的Socket類庫(kù)來給Lua使用:
                1、結(jié)合tolua++進(jìn)行編譯,生成Lua可以調(diào)用的dll文件,請(qǐng)參考網(wǎng)上的資料來熟悉tolua++的使用
                2、假設(shè)dll文件名為MySocket.dll,類為CMySocket,則調(diào)用的時(shí)候類似于:
                    require("MySocket")
                    Instance1 = CMySocket:new()
                    Instance2 = CMySocket:new()
                    Instance1:Listen(9701)
                    Instance2:Connect("127.0.0.1",9701)
            答案:
            windows下編譯lua:
            把etc目錄下的luavs.bat 拷到lua的解壓根目錄下直接運(yùn)行, 生成的.h .dll .lib .exe文件都在src下。
            把相應(yīng)的.h文件和lua51.lib文件拷貝到VC相應(yīng)目錄下。lua.exe和lua51.dll為lua解析器。
            在cygwin下編譯安裝方法:$make linux && make install
            用cygwin編譯安裝tolua++,且不用SCons編譯:
            src/lib下:
            動(dòng)態(tài)鏈接文件:
            gcc -shared -o tolua++.dll *.c /usr/local/lib/lua51.dll -I../../include -I/usr/local/include
            靜態(tài)連接文件:
            gcc -c *.c  -I../../include -I/usr/local/include
            ar rcsv libtolua++.a *.o
            src/bin下:
            執(zhí)行文件,改名為tolua++.exe:
            gcc tolua.c toluabind.c -I../../include -I/usr/local/include -L /usr/local/lib -llua -L../lib/ -ltolua++
            然后把所得到的文件復(fù)制到系統(tǒng)相應(yīng)目錄中。
            根據(jù)mysocket.h設(shè)計(jì)mysocket類模式,寫成.pkg文件。
            產(chǎn)生binding文件mypkg.cpp備用,此時(shí)要用到mysocket.h:tolua++ -o mypkg.cpp mysocket.pkg
            適當(dāng)修改一下生成的mypkg.cpp文件,使以后導(dǎo)出的.dll文件函數(shù)名不變。
            #define TOLUA_API extern "C" __declspec
            用以下方法在cygwin下編譯的.dll文件不能被lua使用,加載包會(huì)失敗。
            g++ -shared -o MySocket.dll *.cpp  /usr/local/lib/lua51.dll -I/usr/local/include -I.. -L /usr/local/lib -ltolua++
            改用VC來編譯。先編譯tolua++。
            把src下除了tolua.c和toluabind_default.x以外的.c和.h都包 含進(jìn)去。工程設(shè)置里要包含LIBC.lib Libcmtd.lib tolua.lib lua5.1.lib,include和lib路徑也要包含lua的。然后設(shè)置#define TOLUA_API extern "C" __declspec編譯成功后就有tolua.lib和tolua.dll文件供接下來的.dll工程使用。
            把bingding文件mypkg.cpp和寫好的mysocket.cpp,mysocket.h一起在VC下編譯生成.dll文件。工程設(shè) 置里要包含LIBC.lib Libcmtd.lib tolua.lib lua51.lib,include和lib路徑也要包含lua或tolua的。前面兩個(gè)文件順序一定不要寫錯(cuò),否則產(chǎn)生如下錯(cuò)誤:
            Linking...
            LIBC.lib(crt0dat.obj) : error LNK2005: __cinit already defined in LIBCMTD.lib(crt0dat.obj)
            編譯產(chǎn)生的MySocket.dll文件就可以被lua調(diào)用了。
            運(yùn)行一個(gè)lua解析器程序?qū)嵗瑘?zhí)行:
            require("MySocket")
            Instance1 = CMySocket:new()
            Instance1:Listen(9701)
            再運(yùn)行另一個(gè)lua解析器程序?qū)嵗瑘?zhí)行:
            require("MySocket")
            Instance2 = CMySocket:new()
            Instance2:Connect("127.0.0.1",9701)
            posted on 2014-06-25 16:32 C++技術(shù)中心 閱讀(3030) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 其他編程
            久久综合久久综合久久| 狠狠色丁香久久婷婷综合图片| 午夜精品久久久内射近拍高清| 国产亚洲美女精品久久久 | 精品无码人妻久久久久久| 999久久久免费国产精品播放| 94久久国产乱子伦精品免费| 一本一本久久a久久精品综合麻豆| 青青久久精品国产免费看| 久久久久人妻一区二区三区| 精品久久久久久国产| 精品久久人人妻人人做精品 | 久久久亚洲欧洲日产国码是AV| 亚洲人成网亚洲欧洲无码久久| 久久99精品久久久久久久不卡| 91精品国产91久久久久久青草| 欧美久久久久久| 亚洲国产精品久久久久网站| 久久婷婷人人澡人人爽人人爱| 日本免费久久久久久久网站| 2021国内精品久久久久久影院| 91性高湖久久久久| 亚洲精品乱码久久久久久按摩| 国产精品成人99久久久久91gav| 亚洲精品白浆高清久久久久久| 久久无码国产| 久久青草国产精品一区| 久久久久亚洲AV无码永不| 91麻豆国产精品91久久久| 国产成人99久久亚洲综合精品 | 久久精品国产亚洲av日韩| 国产精品中文久久久久久久 | 国内精品伊人久久久久AV影院| 伊人久久大香线蕉成人| 久久久久人妻精品一区三寸蜜桃| 国产情侣久久久久aⅴ免费| 精产国品久久一二三产区区别| 亚洲精品高清一二区久久| 精品多毛少妇人妻AV免费久久| 伊人久久综合热线大杳蕉下载| 国内精品久久久久久99|