關(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/CompilingToluappWithoutSconssrc/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)