ããã«ã¡ã¯ååã
ç§ã®å°ããªãããžã§ã¯ãã玹ä»ããããšæããŸããããã¯ããªãã«åœ¹ç«ã€ãšæããŸãã
æ°å¹Žåãé©åºŠãªãµã€ãºãšé«ãããã©ãŒãã³ã¹ãåããçµã¿èŸŒã¿ã¹ã¯ãªããèšèªãæ¢ããŠãããšãã«
ãLuaã«äŒããŸããã Luaã¯ãããã®ããŒãºãæºããã ãã§ãªãããã®é©ãã¹ãã·ã³ãã«ããšè¡šçŸåã«ãé
äºãããŸãã
Lua APIã«äžæºããããšã¯èšããŸãããããã¯äŸ¿å©ã§äœ¿ããããåªããæ©èœã»ããã§ãã èšèªãã¢ããªã±ãŒã·ã§ã³ã«çµ±åããç¬èªã®æ¡åŒµæ©èœã远å ããŠãåé¡ã¯çºçããããèœãšã穎ããçºçããŸããã§ããã ããããããã§ãããã®Cæåã®APIã䜿çšãããšãããã®ããã»ã¹ããã䟿å©ã«ãªãå¯èœæ§ããããšããèããæ®ã£ãŠããŸããã§ããã 䟿å©ãªãªããžã§ã¯ãæåã®ã©ãããŒãäœæããæåã®è©Šã¿ã¯å€±æããŸãããå©çšå¯èœãªè³éã§ã¯ãç§ã¯ååšããã«å€ãããã®ãäœæã§ããŸããã§ããã
ãããŠã
C ++ 11ãç»å Žã ãç§ã劚ãããã¹ãŠã®é害ãåãé€ããïŒããæ£ç¢ºã«-äžè¶³ããŠãããã®ã远å ãããŸããïŒãããºã«ãåŸã
ã«åœ¢ã«ãªãå§ããŸããã 2çªç®ã®ã¢ãããŒãã¯æåãããã®çµæãã»ãšãã©ã®æäœã®èªç¶ãªæ§æã§ããªã軜éãªã©ãããŒã©ã€ãã©ãªãäœæããããšãã§ããŸããã ç§ã
Lua API ++ãšåŒãã ãã®ã©ã€ãã©ãªã¯ã
Lua APIã®äŸ¿å©ãªä»£æ¿åãšããŠæ©èœããããšãç®çãšããŠããŸãã Lua Workshopã§ã®ç§ã®ãã¬ãŒã³ããŒã·ã§ã³ã«åºã¥ãããã®èšäºã¯ãLua API ++ãšãã®æ©èœã®åºæ¬æŠå¿µãçè§£ããã®ã«åœ¹ç«ã¡ãŸãã
䞻圹
ç¥ãåãã¯ãã©ã€ãã©ãªã§äœ¿çšãããåºæ¬æŠå¿µãšããããã®é¢ä¿ããå§ããå¿
èŠããããŸãã äºæ³ã©ããããããã®æŠå¿µã¯å¯Ÿå¿ããã¿ã€ãã«åæ ãããŠããŸãã
State
State
ã¯Luaå·ã®ææè
ã§ãã ããã¯ç¬ç«ããã¿ã€ãã§ãããä»ã®ã©ã€ãã©ãªãšã¯å®è³ªçã«ç¡é¢ä¿ã§ãã ç¶æ
ã®äœæãšç Žæ£ã®å¶åŸ¡ã«å ããŠããã¡ã€ã«ãæååãããã³Luaäºææ©èœãå®è¡ããææ®µã®ã¿ãæäŸããŸãã æäœäžã«çºçãããšã©ãŒã¯äŸå€ã«å€æãããŸãã
LFunction
ã©ã€ãã©ãªå
ã®ä»ã®ãã¹ãŠã¯ã
LFunction
ãLua API ++ãšäºææ§ã®ããç¹å¥ãªåœ¢åŒã®é¢æ°å
ã§çºçããŸãã ããã¯Luaäºææ©èœã«é¡äŒŒããŠããã
CFunction
ãšããååãä»ããããŠã
CFunction
ã äž»ã«æ¬¡ã®æåãå
¥ããããã«ãç¹å¥ãªé¢æ°åœ¢åŒãå¿
èŠã§ããïŒ
Context
Context
ã¯ã颿°ã®ã³ã³ããã¹ãã§ãããLuaã®ãã¹ãŠã®æ©èœãžã®ã¢ã¯ã»ã¹ã»ã³ã¿ãŒã§ãã ããã䜿çšããŠãã°ããŒãã«å€æ°ã颿°ã®åŒæ°ã
ã¬ãžã¹ããªãããã³
upvaluesã«ã¢ã¯ã»ã¹ã§ããŸãã ã¬ããŒãžã³ã¬ã¯ã¿ã管çãããšã©ãŒãéç¥ããè€æ°ã®æ»ãå€ãæž¡ããé害ãäœæã§ããŸãã ç°¡åã«èšãã°ã
Context
ãéããŠããã¬ãŒãªã³ã°ã®ç¹æš©ã§ããå€ã®æäœã«çŽæ¥é©çšãããªããã¹ãŠãè¡ãããŸãã
䟡å€
åãååã®ã¯ã©ã¹ãæç¢ºã«å¯Ÿå¿ããŠãã以åã®æŠå¿µãšã¯ç°ãªããLua API ++ã®ãå€ãã¯ããææ§ã§ãïŒãã¡ããã
Value
ã¯ã©ã¹ã¯ååšããŸãïŒã ããã¯äž»ã«ãããªãŒãã³ããŒããŒãããªã·ãŒã«ãããã®ã§ãLuaã§ãã€ãã£ãå€ãèªç±ã«ç§»è¡ã§ãããã®éãå¯èœã§ãã Luaã®å€ãäºæ³ãããå Žåã¯ãã€ã§ãããµããŒããããŠããåã®ãã€ãã£ãå€ã眮ãæããããšãã§ãããããã¯èªåçã«Luaã¹ã¿ãã¯ã«ãç§»åãããŸãã æé»ã®å倿æŒç®åã¯ãå€ãå察æ¹åã«ç§»åããã®ã«åœ¹ç«ã¡ãŸããå®éã®åãšæåŸ
ãããåã«äºææ§ããªãå Žåã¯ãäŸå€ã§ãããéç¥ããŸãã
ããã«ãLuaã®å€ã¯ããã®èµ·æºã«å¿ããŠãå
±éã®ã€ã³ã¿ãŒãã§ãŒã¹ããµããŒãããããŸããŸãªã¿ã€ãã§è¡šãããšãã§ããŸãã ãã®ã€ã³ã¿ãŒãã§ã€ã¹ã¯ãå€ã«å¯Ÿãããã¹ãŠã®æå¹ãªæäœãå®è£
ããŸãããã€ãã£ãåãžã®æç€ºçããã³æé»çãªå€æã颿°åŒã³åºããã€ã³ããã¯ã¹ä»ããç®è¡æŒç®ãæ¯èŒãåãã§ãã¯ãã¡ã¿ããŒãã«ã®æžã蟌ã¿ããã³èªã¿åãã
Valref
ããã¯ãã¹ã¿ãã¯ã«é
眮ãããå€ãžã®ãªã³ã¯ã§ãããããããLuaã¹ã¿ãã¯ã®ç¹å®ã®ã¹ãããã»ã©ã§ã¯ãããŸããã
Valref
ã¯ãã¹ã¿ãã¯äžã®å€ã®é
眮ãŸãã¯åé€ã
Valref
ããŸããããå€ã®æäœã®ã¿ã«çŠç¹ãåãããŸãã Lua API ++
Valref
ã¯ãå€ã衚ãä»ã®ã¿ã€ãã®ã€ã³ã¿ãŒãã§ãŒã¹ã«åŸãã¢ãã«ãšããŠæ©èœããŸãã
äžæçãª
æäœã®çµæã§ããäžæçãªå€ã§ã¯ãããè€éã§ãã ãããã¯ãæäœã®çµæãšããŠã¹ã¿ãã¯ã«
ããã·ã¥ããã ïŒãŸãã¯
ããã·ã¥ãããªãïŒå€ã§ããã
äžåºŠäœ¿çšãããŠããåé€ãããŸãã ããã«ãæäœèªäœã®åŒæ°ã¯ä»ã®æäœã®çµæã§ããå Žåããããæåãä¿èšŒãããã®ã§ã¯ãããŸããã ãŸããäœ¿çšæ¹æ³ãç°ãªãå ŽåããããŸããã¹ã¿ãã¯ã§ã®èªã¿åãã®çµæãšããŠã€ã³ããã¯ã¹ãäœæãããšãããŒã®ä»£ããã«æ°ããå€ãäœæãããæžã蟌ã¿ã®çµæãšããŠãããŒãšèšé²ãããå€ãã¹ã¿ãã¯ããåé€ãããŸãã æäœã®åŒæ°ã®é
眮é åºãå³å¯ã«ç£èŠããå¿
èŠæ§ã«ã€ããŠã¯ã©ãã§ããïŒ ãããŠãæªäœ¿çšã®ãªããžã§ã¯ããã©ããããïŒ
å€ãã®äººã¯ãããããç§ãäœãåŸãŠãããããã§ã«æšæž¬ããŠããã§ãããã äžæçãªå€ã¯ãããã·ã¿ã€ãã«ãã£ãŠè¡šãããŸãã ãããã¯ããŠãŒã¶ãŒãç®ã«èŠããªãããã«ãã³ãã¬ãŒãã§èšèšãã
Valref
ã€ã³ã¿ãŒãã§ãŒã¹ãåçŸããŸãã ãããã®äœ¿çšã¯ç°¡åãç°¡åã䟿å©ã§ãããééããç¯ããšãã³ã³ãã€ã©ãŒã¯å±±æ¬åŒ§ã§ãã£ã±ãã®èšå€§ãªæ§æã§ãåãã§ããããŸãã
ã¢ã³ã«ãŒ
ã¢ã³ã«ãŒã«ã¯ã1ã€ä»¥äžã®å€ãã¹ã¿ãã¯ã«ãåºå®ãã§ãããããååãä»ããããŠããŸãã
Value
ã¯åäžã®å€ã®æ±çšçãªãã¢ã³ã«ãŒãã§ããã
Table
ããŒãã«å°çšã§ããã
Valset
ã¯è€æ°ã®å€ãæ ŒçŽããŸãã
ã¡ã€ã³ãã£ã©ã¯ã¿ãŒã衚瀺ãããã®ã§ããããã䜿çšããŠäœãã§ãããã«ã€ããŠããã詳现ãªåæãéå§ã§ããŸãã
State
State
ã¯ãã³ã³ããã¹ãã®åæåã«å¿
èŠãªãã¹ãŠã®ã¢ã¯ã·ã§ã³ãå®è¡ããããã©ã«ãã®ã³ã³ã¹ãã©ã¯ã¿ãŒããããŸãã å¥ã®ã³ã³ã¹ãã©ã¯ã¿ãŒã䜿çšãããšã
ã«ã¹ã¿ã ã¡ã¢ãªç®¡ç颿°ã䜿çšã§ããŸãã
getRawState
颿°ã«ãããLua APIã§äœ¿çšãããç¶æ
ãªããžã§ã¯ããžã®çã®ãã€ã³ã¿ãŒãèŠæ±ã§ããŸãã
ãã®ã»ããã«ã¯ã颿°
runFile
ã
runString
ãããã³
call
å«ãŸããŠãããç°¡åãªã€ã³ã¿ãŒããªã¿ãŒãäœæã§ããŸãã
æãåçŽãªã€ã³ã¿ãŒããªã¿ãŒ #include <iostream> #include <luapp/lua.hpp> using namespace std; using namespace lua; void interpretLine(State& state, const string& line) { try { state.runString(line); // } catch(std::exception& e) { // cerr << e.what() << endl; } } void interpretStream(State& state, istream& in) { string currentLine; while(!in.eof()) { // getline(in, currentLine); interpretLine(state, currentLine); } } int main() { State state; interpretStream(state, cin); }
ãšã©ãŒåŠç
ã©ã€ãã©ãªã§äœ¿çšãããã¢ãããŒãã¯ãLuaã®è¶³å
ã«åãŸãããšã§ã¯ãªãããã
Table
ããã§ã¯ãªã
Table
ãäœæããããšãããªã©ãã©ã€ãã©ãªèªäœã«é¢é£ãããšã©ãŒã蚺æããããããŠãŒã¶ãŒã³ãŒãã§ïŒããããïŒã€ã³ã¿ãŒã»ããããå¿
èŠããããšã©ãŒã蚺æãããŸããåãã£ã¹ããšã©ãŒã®ããã«ã ã©ã€ãã©ãªã¯ãLua APIã®åŒã³åºãæã«æ€åºãããå¯èœæ§ã®ãããšã©ãŒãäºåã«èšºæããããšããŸããã ãããã£ãŠãããšãã°ãå®éã«æ°å€ã§ããå€ã«å¯ŸããŠé¢æ°åŒã³åºãã䜿çšããããšããŠããäŸå€ã¯çºçããŸããã
lua_call
åŒã³åºãå
ã§æ€åºãããLuaã¹ã¿ã€ã«ã®ãšã©ãŒïŒå®è¡ã®äžæãšä¿è·ãããåŒã³åºãã®æãè¿ããã€ã³ãã«æ»ãïŒãçºçããŸãã
LFunction
å®éãã©ã€ãã©ãªã¯ããµããŒããããŠããåïŒããã³ã¡ã³ããŒé¢æ°ïŒã§åäœãã颿°ã®ãéæãªãã©ãããŒããµããŒãããŠããŸãã Luaå€ãæåŸ
ããã颿°ã®ååãåã«è¿°ã¹ãŠãã ããã ããããLua API ++ãæäŸãããã¹ãŠã®Luaã¢ã¡ããã£ã«ã¢ã¯ã»ã¹ããå Žåã¯ããã®ãããã¿ã€ãã«åŸã£ãŠL颿°ãèšè¿°ããå¿
èŠããããŸãã
Retval myFunc(Context& c);
ããã§ã¯ãã¹ãŠãç°¡åã§ãã颿°ã¯
Context
ãåãåãã
Retval
ã¯
Context::ret
颿°ãä»ããŠä»»æã®æ°ã®å€ãç°¡åã«è¿ãã®ã«åœ¹ç«ã€ç¹å¥ãªåã§ãã
mkcf
ãã³ãã¬ãŒãã䜿çšãããšã
LFunction
Luaãåéã«ã§ããŸãã
int (*myCfunc)(lua_State*) = mkcf<myFunc>;
ãã®ããã«ããŠã颿°ã®ã©ãããŒãæç€ºçã«äœæã§ããŸãã ãéæãªãã©ãããŒãæ©èœããŸããããªãŒããŒãããã¯ãããã«é«ããªããŸãã äžæ¹ã
mkcf
ã¯ããããã®å Žåã«åå¥ã®ã©ãããŒé¢æ°ãäœæããŸãã
ãããã«ããŠãããã©ãããŒãã¯
Context
ãªããžã§ã¯ããäœæããŠé¢æ°ã«æž¡ããäœæ¥ãå®äºãããšã
Retval
ãéããŠ
Retval
ããå€ãLuaã«æž¡ããŸãã ã©ããããã颿°ã®ã¹ã³ãŒããè¶
ãããã¹ãŠã®äŸå€ã¯ãã£ãããããLuaãšã©ãŒã«å€æãããŸãã
颿°ã¯ããèªäœãè¿ããŸããïŒ ã¡ããã ãïŒ Retval retSelf(Context& c) { return c.ret(retSelf, mkcf<retSelf>);
Context
颿°ã³ã³ããã¹ãã¯ãLuaãžã®äžå€®ã¢ã¯ã»ã¹ããŒãã§ãã å€ã®æäœã«çŽæ¥é¢ä¿ããªããã¹ãŠã¯ã
Context
ä»ããŠè¡ãããŸãã ç§ã¯
god objectã«æç¢ºã«äŒŒãŠãããšãããã³ããæåŠããŸãããããã®å Žåããã®ãããªæ±ºå®ã¯Lua APIã®ã¢ãŒããã¯ãã£ã«ãã£ãŠæ±ºå®ãããŸãã
Context
ä»ããŠãã¬ããŒãžã³ã¬ã¯ã¿ãŒãå¶åŸ¡ããã¹ã¿ãã¯ã«é
眮ãããããŒãžã§ã³çªå·ãšå€ã®æ°ã確èªã§ããŸãã Lua APIãçŽæ¥äœ¿çšããå¿
èŠãããå Žåã«åããŠãæé»çã«
lua_State*
ã«å€æãããŸãã ãã®å Žåãããžãã¯
LFunction
ïŒããæ£ç¢ºã«ã¯ãä¿¡å·ã¿ã€ãã®éç宿°ïŒã
initializeExplicitly
ã
initializeExplicitly
ãããã¯
initializeExplicitly
ãããã«ããã
LFunction
å€éšã§
Context
æç€ºçã«äœæã§ããŸãã
æ»ãå€
returnã¹ããŒãã¡ã³ãã§é¢æ°ããè¿ãããå€ãåçŽã«ç€ºãã®ãã©ããªã«çŽ æŽããããšããŠããããã¯äžå¯èœã§ãã 2ã€ã®æãè¿ãéžæè¢ããéžæããå¿
èŠããããŸãããã«ã³ãããªãŒããŒããŒããããæŒç®åãŸãã¯é¢æ°åŒã³åºãã䜿çšããcãªãã¹ã¿ãŒã¿ãŒãã§ãã
ãã¬ã³ãã·ããæ©èœãåã¡ãŸããã ãããã£ãŠã
LFunction
ã¯
LFunction
å¿
èŠããããŸããããã¯ãæ§ãããªåå
ret
Context
ã¡ãœããã«ã¢ã¯ã»ã¹ããããšã«ãã£ãŠã®ã¿äœæã§ããŸãã ããã¯ç¹å¥ãªé¢æ°ã§ããåŒã³åºãããåŸãã¹ã¿ãã¯ããã®å€ãæšãŠãªãããã«ã¹ã¿ãã¯ã忢ããŸãããããã£ãŠã
returnã¹ããŒãã¡ã³ãã§ã®ã¿çŽæ¥äœ¿çšããå¿
èŠããããŸãã
ret
åŒã³åºãã§ã¯ãå¿
èŠãªæ°ã®æ»ãå€ããªã¹ãã§ããŸãã
æ¯èŒ return ctx.ret(1, "two", three);
åçã®ã³ãŒãïŒ
lua_pushinteger(ctx, 1); lua_pushstring(ctx, "two"); lua_pushvalue(ctx, three); return 3;
ãšã©ãŒå ±å
Retval
ãäœæããå¯äžã®æ¹æ³ã¯
ret
颿°ã䜿çšããããšã§ãããšäž»åŒµããŠãç§ã¯çå®ã«çœªãç¯ããŠããŸãããã1ã€ã®èŠåããããŸã...æ£åŒãªèгç¹ããããã®ã¿ã€ããè¿ã
error
颿°ããããŸãã å®éã
Retval
ãäœæã«å°éããªãã®ã¯ããã®é¢æ°ããã®ãªã¿ãŒã³ããªãããã§ãã æåŸ
ã§ããæå€§å€ã¯ãã¡ãã»ãŒãžãLuaãšã©ãŒåŠçãšã³ãžã³ã«æž¡ãããšã§ãã Lua APIããã¥ã¡ã³ãã§ã¯ã
returnã¹ããŒãã¡ã³ãã§
lua_error
åŒã³åºãã䜿çšããŠãåŒã³åºãäžã«é¢æ°ãäžæãããããšã瀺ãããšãæšå¥šããŠããŸãã åãã¢ãããŒããLua API ++ã§ã䜿çšãããŠããããã
error
Retval
ãè¿ã
error
宣èšãããŠã
Retval
ã
ãšã©ãŒã¡ãã»ãŒãžãå«ãLuaå€ãåŒæ°ãšããŠäœ¿çšãããç¹ã«
where
颿°ãæååãäœæããŠçŸåšã®é¢æ°ã説æããè¡ãäœæã§ãããããããã§ã®é£çµã¯éåžžã«é©åã§ãã ã¡ãã»ãŒãžããŸã£ããæå®ãããŠããªãå Žåãåãå€ã䜿çšãããŸãã
if(verbose) return ctx.error(ctx.where() & " intentional error " & 42); else return ctx.error();
åçã®ã³ãŒã if(verbose) { luaL_where(ctx, 0); lua_pushstring(ctx, " intentional error "); lua_pushinteger(ctx, 42); lua_concat(ctx, 3); return lua_error(ctx); } else { luaL_where(ctx, 0); return lua_error(ctx); }
ç°å¢ãžã®ã¢ã¯ã»ã¹
ç§ãã¡ã®
Context
ã¯æããã«äŸ¡å€ã®äž»ãªæºã§ãã å®éã圌ãã¯ã©ãããæ¥ãã®ã§ããããïŒ
Context
ã¯ã©ã¹ã®ãããªãã¯ã¡ã³ããŒãšããŠèšèšãããã¢ã¯ã»ã¹ãªããžã§ã¯ããæäŸãããŠãããããç°å¢ã®ããŸããŸãªè峿·±ãå Žæã«ã¢ã¯ã»ã¹ã§ããŸãã ãããã¯ãã¹ãŠãå€ã®èªã¿åããšæžã蟌ã¿ãèš±å¯ããŸãã
ãŸã第äžã«ãããã
args
ã颿°ã®åŒæ°ã§ãã ãŠãŒã¶ãŒãã¢ã¯ã»ã¹ã§ããªãç¹å¥ãªã¿ã€ããäœæãããä»ã®ã¢ã¯ã»ã¹ãªããžã§ã¯ããšã¯ç°ãªããéåžžã®å®æ°
Valset
ãããã§äœ¿çšãããŸãã ãã®äžå€æ§ãšã¯ããµã€ãºã倿Žã§ããªãããšã ããæå³ããŸãããåŒæ°ã®æå³ãæžãæããããšã¯å¥åº·ã®ããã§ãã Valsetã¯STLäºæã®ã³ã³ãããšããŠäœæãããããããã®äžã®èŠçŽ ã®çªå·ä»ãã¯0ããå§ãŸããŸããä»ã®å Žåãã©ã€ãã©ãªã¯Luaã®èŠåã«åŸããã€ã³ããã¯ã¹ä»ãã1ããå§ãŸãããšãæå³ããŸãã
if(ctx.args.size() > 1 && ctx.args[0].is<string>()) {...};
åçã®ã³ãŒã if(nArgs > 1 && lua_isstring(ctx, 1) ) {...};
2çªç®ã¯ãã°ããŒãã«å€æ°ãžã®ã¢ã¯ã»ã¹ã§ãã
global
ãªããžã§ã¯ãã¯ãæååã«ãã£ãŠã€ã³ããã¯ã¹ä»ããããŸãã
ctx.global["answer"] = 42;
åçã®ã³ãŒã lua_pushinteger(ctx, 42); lua_setglobal(ctx, "answer");
LFunctionãã¯ããŒãžã£ã§ããå ŽåãæŽæ°ã€ã³ããã¯ã¹ïŒ1ããå§ãŸããã¹ãŠã®å€ãæ£ããïŒã䜿çšããŠãå€ã«æ ŒçŽãããŠããå€ã«ã¢ã¯ã»ã¹ã§ããŸãã æ ŒçŽãããŠããå€ã®æ°ãç¥ãæ¹æ³ã¯ãããŸãããããã¯ãã§ã«ããã£ãŠãããšæ³å®ãããŠããŸãã
ã¬ãžã¹ããªããã¢ã¯ã»ã¹ã§ããLuaã¬ãžã¹ããªã¯ã2ã€ã®æ¹æ³ã§äœ¿çšãããŸãã æååããŒã«ããããŠãŒã¶ãŒããŒã¿ã®ã¡ã¿ããŒãã«ãããã«æ ŒçŽãããŸãã æŽæ°ããŒã¯ãã¬ãžã¹ããªãå€ã®ã¹ãã¢ãšããŠäœ¿çšãããšãã«äœ¿çšãããŸãã ããŒã¯ã
registry.store
ãåŒã³åºãããšã«ãã£ãŠäœæããããã®åŸ
registry.store
ãžã®èªã¿åããšæžã蟌ã¿ã«äœ¿çšãããå€ãæ¶å»ãããããŒãè§£æŸããããšã
nil
æžã蟌ãŸããŸãã
auto k = ctx.registry.store(ctx.upvalues[1]);
åçã®ã³ãŒã lua_pushvalue(ctx, lua_upvalueindex(1)); auto k = luaL_ref(ctx, LUA_REGISTRYINDEX); luaL_unref(ctx, LUA_REGISTRYINDEX, k);
æ©èœ
å
ã»ã©ãLuaã䜿çšããŠã¯ããŒãžã£ãäœæã§ãããšè¿°ã¹ãŸããã
Context
ãªããžã§ã¯ãã¯ããã«
closure
颿°ã䜿çšããŸãã
closure
颿°ã¯ã
CFunction
ãšã¯ããŒãžã£ãŒã«æ ŒçŽãããå€ãåãåããŸãã çµæã¯äžæãªããžã§ã¯ããã€ãŸãå®å
šãªLuaå€ã§ãã
CFunction
代ããã«ã
CFunction
ãããã«æå®ã§ããŸããããã®æããã«ã¯ç¬èªã®äŸ¡æ ŒããããŸãã æåã®äžäœå€ã¯ãçµæã®ã¯ããŒãžã£ãŒã§äºçŽãããŸãïŒã©ãããŒã¯ã©ã®LFunctionã§ãåãã§ããããã颿°ã®ã¢ãã¬ã¹ã¯ããã«æ ŒçŽãããŸãïŒã åã颿°ã
LFunction
ééçãªç§»è¡ã«äœ¿çšãããåãçµæã«ãªããŸãã ããã¯ãäœãäºçŽããªã
mkcf
ãã³ãã¬ãŒããšã®éãã§ããã颿°ããšã«åå¥ã®ã©ãããŒé¢æ°ãäœæããŸãã
ãã£ã³ã¯ãäœæããããšãã§ããŸãïŒã³ã³ãã€ã«ãããLuaã³ãŒãã ããã¹ãèªäœã¯
chunk
ã¡ãœããã䜿çšããŠã³ã³ãã€ã«ããããã¡ã€ã«ã®ã³ã³ãã³ãã¯
load
ã䜿çšããŠã³ã³ãã€ã«ãã
load
ã ãå®äºããŠå¿ãããããå Žåã
runString
ãšãŸã£ããåã
runString
ãš
runFile
ããããŸãã 䜿çšã«é¢ããŠã¯ããã£ã³ã¯ã¯äžè¬çãªæ©èœã§ãã
wrap
ã¡ãœããã䜿çšããŠãäºææ§ã®ãªã颿°ããã¯ããŒãžã£ãŒãäœæããããšãã§ããŸãã Luaã¹ã¿ãã¯ããåŒæ°ãåãã颿°ã§åãå
¥ããããå€ã«å€æããåŒã³åºããè¡ããçµæãæ»ãå€ãšããŠLuaã¹ã¿ãã¯ã«é
眮ããã©ãããŒãèªåçã«äœæããŸãã ããã©ã«ãã§ã¯ãããã¯ãŠãŒã¶ãŒããŒã¿ãå«ããã¹ãŠã®ãµããŒããããŠããã¿ã€ãã§æ©èœããŸãã ããã§ååã§ãªãå ŽåïŒããšãã°ã
vector
ã«æ ŒçŽãããè¡ã§äœããããå¿
èŠãããå Žåã
ç¹å¥ãªãã¯ãã䜿çšããŠãããæ¹åãŸãã¯å¥ã®æ¹åãžã®å€æãæå®ããããšãã§ããŸãã
颿°ãæé»çã«ç§»è¡ãããšãã«æ©èœããã®ã¯wrap
ã å
åŒã®vwrap
ã¡ãœããã¯ã»ãšãã©ãã¹ãŠåãããšãè¡ããã©ããããã颿°ã«ãã£ãŠè¿ãããå€ã®ã¿ãç¡èŠããŸãã
䟡å€ã®ç§»è¡
Lua API ++ã¯ã次ã®ãã€ãã£ãã¿ã€ãããµããŒãããŠããŸãã
æ°å€ |
---|
int |
unsigned int |
long long |
unsigned long long |
float |
double |
ã²ã |
---|
const char* |
std::string |
æ©èœ |
---|
CFunction: int (*) (lua_State*) |
LFunction: Retval (*) (Context&) |
ä»»æã®é¢æ° |
ã¡ã³ããŒé¢æ° |
éå€ |
---|
Nil |
bool |
LightUserData: void* |
ç»é²ãŠãŒã¶ãŒã¿ã€ã |
衚ã«ãªã¹ããããŠããåã®å€ã¯Luaã¹ã¿ãã¯ã«ç§»è¡ã§ãããã®éãå¯èœã§ãïŒãã¡ããã Nil
ãšãã©ãããŒã颿°ã¯äŸå€ã§ãã©ãããŒãžã®ãã€ã³ã¿ãŒã®ãŸãŸã§ãïŒã
å€åã«çµã¿èŸŒãŸããæé»çãªå€ææŒç®åãšcast
ãã³ãã¬ãŒã颿°ã䜿çšããŠãéç§»è¡ãå®è¡ãããŸããLuaå€ã«ãç®çã®ããŒã¿ã«å€æã§ããªãããŒã¿ãå«ãŸããŠããå ŽåãäŸå€ãã¹ããŒãããŸãã optcast
颿°ã¯ãäŸå€ã§ã¯ãªãããã©ãŒã«ããã¯ãå€ãè¿ããŸãã
int a = val; auto b = val.cast<int>(); auto c = val.optcast<int>(42);
åçã®ã³ãŒã if(!lua_isnumber(ctx, valIdx)){ lua_pushstring(ctx, "Conversion error"); return lua_error(ctx); } int a = lua_tointeger(ctx, valIdx); if(!lua_isnumber(ctx, valIdx)){ lua_pushstring(ctx, "Conversion error"); return lua_error(ctx); } auto b = lua_tointeger(ctx, valIdx); auto c = lua_isnumber(ctx, valIdx) ? lua_tointeger(ctx, valIdx) : 42;
is
颿°ã䜿çšããŠç®çã®åãšã®äºææ§ã確èªããtypeã䜿çšããŠãä¿åãããŠããå€ã®åãçŽæ¥ç¢ºèªã§ããŸãã
if(val.is<double>()) ...; if(val.type() == ValueTypes::Number) ...;
åäžå€æäœ
å²ãåœãŠ
Valueãããå Žåãäžè¬çãªã±ãŒã¹ã§ã¯ãä»ã®Valueãšãã€ãã£ãã®äž¡æ¹ã«äœããå²ãåœãŠãããšãã§ããŸãã ãã ããããã¯äžæçãªå€ãããšãã°é¢æ°åŒã³åºãã®çµæãé·ãã«ã¯é©çšãããŸããã =
èšå·ã®å·ŠåŽã«ãããšãããªãããŒãªãšã©ãŒãçºçããŸãã ãã ããã€ã³ããã¯ã¹ä»ããã¡ã¿ããŒãã«ãªã©ããã®ä»ã®äžæçãªå€ã®å²ãåœãŠã¯éåžžã«åãå
¥ããããŸãã å®è¡ãããã¢ã¯ã·ã§ã³ã®æå³ã«åŸã£ãŠãå²ãåœãŠããããã®ãšã§ããªããã®ãæšæž¬ããã®ã¯ç°¡åã§ãã
ã¡ã¿ããŒãã«
mt
ã¡ãœããã¯ãèªã¿åããšæžã蟌ã¿ãå¯èœãªå€ã®ã¡ã¿ããŒãã«ãžã®ã¢ã¯ã»ã¹ãæäŸããŸãã
{ Table mt = val.mt(); val.mt() = nil; }
åçã®ã³ãŒã if(!lua_getmetatable(ctx, valIdx)){ lua_pushstring(ctx, "The value has no metatable"); return lua_error(ctx); } int mtIdx = lua_gettop(ctx); lua_pushnil(ctx); lua_setmetatable(ctx, valIdx); lua_pop(ctx, 1);
é·ã
len
颿°ã®æäœã¯ãLuaã®ããŒãžã§ã³ã«ãã£ãŠç°ãªããŸãã5.1äºæã¢ãŒãã§ã¯ãã€ãã£ãã®size_t
è¿ãã5.2ã¢ãŒãã§ã¯äžæçãªå€ãè¿ããŸãã
玢åŒä»ã
ããŒãã«ã®ããŒèŠçŽ ã¯ã€ã³ããã¯ã¹ã«ãã£ãŠã¢ã¯ã»ã¹ãããããŒã¯ãµããŒããããŠããä»»æã®ã¿ã€ãã«ããããšãã§ããŸãã ãã ãã颿°ãã©ãããããšãæ°ããã¯ããŒãžã£ãäœæãããããšãèŠããŠããå¿
èŠããããŸãã
void myFunc(); Retval example(Context& c) { Table t(c); t[myFunc] = 42;
åçã®ã³ãŒã void myFunc(); int wrapped_void_void(lua_State* s) { if(!lua_islightuserdata(ctx, lua_upvalueindex(1))) { lua_pushstring(ctx, "Conversion error"); return lua_error(ctx); } void (*fptr) () = reinterpret_cast<void(*)()>(lua_touserdata(ctx, lua_upvalueindex(1))); fptr(); return 0; } int mkcf_myFunc(lua_State* s) { myFunc(); return 0; } int example(lua_State* ctx) { lua_createtable(ctx, 0, 0); int t = lua_gettop(ctx); lua_pushlightuserdata(ctx, reinterpret_cast<void*>(&myFunc)); lua_pushcclosure(ctx, &wrapped_void_void, 1); lua_pushinteger(ctx, 42); lua_settable(ctx, t); lua_pushlightuserdata(ctx, reinterpret_cast<void*>(&myFunc)); lua_pushcclosure(ctx, &wrapped_void_void, 1); lua_gettable(ctx, t); assert(lua_isnil(ctx, -1)); lua_pushcfunction(ctx, &mkcf_myFunc); lua_pushnumber(ctx, 42.42); lua_settable(ctx, t); lua_pushcfunction(ctx, &mkcf_myFunc); lua_gettable(ctx, t); lua_pushnumber(ctx, 42.42); int result = lua_compare(ctx, -1, -2, LUA_OPEQ); lua_pop(ctx, 2); assert(result == 1); }
颿°åŒã³åºã
Lua颿°ã¯ãéåžžã®æ¬åŒ§ã䜿çšããŠåŒã³åºãããŸãã ãã£ãšè¡šçŸåè±ããªãã®ãå¿
èŠãªå Žåã®ããã«ãæç€ºçãªåŒã³åºãã®ããã®call
ã¡ãœããããããŸãã pcall
åŒã³åºãã¯ãšã©ãŒãé²ããŸãã
int x = fn(1); int y = fn.call(1);
è€æ°ã®æ»ãå€
åŒã³åºãã®çµæãéåžžã®å€ãšããŠå®å
šã«äœ¿çšã§ããããšãããããŸããã ããããäžåºŠã«è€æ°ã®å€ãè¿ã颿°ã¯ã©ãã§ããããïŒ ããšãã°ãLuaã§ãã®ãããªé¢æ°ã䜿çšããŸãã function mrv() return 2, 3, 4; end
äžåºŠã«ããã€ãã®ãªãã·ã§ã³ããããŸãã
ãŸããåŒã³åºãåŒã䜿çšããã«åŒã³åºãã®çµæãå®å
šã«ç¡èŠã§ããŸãã è¿ããããã¹ãŠã®å€ã¯åçŽã«ã¹ããŒãããŸãã
mrv();
åçã®ã³ãŒã lua_pushvalue(ctx, mrvIdx); lua_call(ctx, 0, 0);
次ã«ãåŒã³åºãåŒãéåžžã®Luaå€ãšããŠäœ¿çšã§ããŸãã æ¬¡ã«ãæåã«è¿ãããå€ã®ã¿ã䜿çšããïŒé¢æ°ãäœãè¿ããªãå Žåã¯nil
ïŒãæ®ãã¯åã³ã¹ããŒãããŸãã
Value x = mrv();
åçã®ã³ãŒã lua_pushvalue(ctx, mrvIdx); lua_call(ctx, 0, 1); int x = lua_gettop(ctx);
第äžã«ãå€ã®ã·ãŒã±ã³ã¹ïŒããšãã°ã颿°ãã©ã¡ãŒã¿ãŒïŒãå«ãã³ã³ããã¹ãã§ã¯ãåŒã³åºãåŒãå±éãããŸãïŒè¿ãããå€ã¯ã·ãŒã±ã³ã¹ã®äžéšã«ãªããŸãã
print(1, mrv(), 5);
åçã®ã³ãŒã lua_pushvalue(ctx, printIdx); int oldtop = lua_gettop(ctx); lua_pushinteger(ctx, 1); lua_pushvalue(ctx, mrvIdx); lua_call(ctx, 0, LUA_MULTRET); lua_pushinteger(ctx, 5); int nArgs = lua_gettop(ctx) - oldtop; lua_call(ctx, nArgs, 0);
第4ã«ããã®ããã«Valset
ã«èæ¡ããããã¹ãŠãValset
ã«ä¿åããããšãã§ããŸãã
Valset vs = mrv.pcall();
åçã®ã³ãŒã int vsBegin = lua_gettop(ctx) + 1; lua_pushvalue(ctx, mrvIdx); bool vsSuccess = lua_pcall(ctx, 0, LUA_MULTRET) == LUA_OK; int vsSize = lua_gettop(ctx) + 1 - vsBegin;
Valset
ã¯ãä¿è·ãããåŒã³åºããæåãããã©ãããèšæ¶ããŸãïŒãã®æ
å ±ãååŸããå¯äžã®æ¹æ³ã§ãïŒã 倱æããå Žåã¯ããšã©ãŒã¡ãã»ãŒãžãå«ãŸããŸãã å¬ããããšã«ã Valset
ã¯åŒã³åºãåŒãšåãæ¹æ³ã§å€ã®ãªã¹ãã«å±éã§ããŸãã
print(1, vs, 5);
åçã®ã³ãŒã lua_pushvalue(ctx, printIdx); int oldTop = lua_gettop(ctx); lua_pushInteger(ctx, 1); lua_pushvalue(ctx, mrvIdx); for(auto i = 0; i < vsSize; ++i) lua_pushvalue(ctx, vsBegin + i); lua_pushinteger(ctx, 5); int nArgs = lua_gettop(ctx) - oldtop; lua_call(ctx, nArgs, 0);
Valset
. STL- STL, «» Valref
. Valset
, push_back
pop_back
. Valref
, ( Valset
), . , .
, Value- , :
string s = "The answer to question " & val & " is " & 42;
lua_pushstring(ctx, "The answer to question "); lua_pushvalue(ctx, valIdx); lua_pushstring(ctx, " is "); lua_pushinteger(ctx, 42); lua_concat(ctx, 4); string s = lua_tostring(ctx, -1); lua_pop(ctx, 1);
& . , «» . , Valset
.
Lua, .
5.2 , , «» ^
.
, Table
, Valref
. , , , . raw
, , , iterate
, for_each
. , iterate
( , , ), -. Valref
true
, false
, . :
Table t = ctx.global["myTable"]; t.iterate([] (Valref k, Valref v) { cout << int(k) << int(v); });
lua_getglobal(ctx, "myTable"); if(!lua_istable(ctx, -1)){ lua_pushstring(ctx, "Conversion error"); return lua_error(ctx); } int t = lua_gettop(ctx); lua_pushnil(ctx); size_t visited = 0; while(lua_next(ctx, t)) { ++ visited; if(!lua_isnumber(ctx, -2) || !lua_isnumber(ctx, -1)){ lua_pushstring(ctx, "Conversion error"); return lua_error(ctx); } cout << lua_tointeger(ctx, -2) << lua_tointeger(ctx, -1); lua_pop(ctx, 1); }
iterate
.
Table
â array
records
. .
fn(Table::array(ctx, "one", 42, Table::array(ctx, 1, 2, 3)));
lua_pushvalue(ctx, fn); lua_createtable(ctx, 3, 0); lua_pushinteger(ctx, 1); lua_pushstring(ctx, "one"); lua_settable(ctx, -3); lua_pushinteger(ctx, 2); lua_pushinteger(ctx, 42); lua_settable(ctx, -3); lua_pushinteger(ctx, 3); lua_createtable(ctx, 3, 0); lua_pushinteger(ctx, 1); lua_pushinteger(ctx, 1); lua_settable(ctx, -3); lua_pushinteger(ctx, 2); lua_pushinteger(ctx, 2); lua_settable(ctx, -3); lua_pushinteger(ctx, 3); lua_pushinteger(ctx, 3); lua_settable(ctx, -3); lua_settable(ctx, -3); lua_call(ctx, 1, 0);
, . , array
, 1. , Valset
.
records
, -. .
x.mt() = Table::records(ctx, "__index", xRead, "__newindex", xWrite, "__gc", xDestroy );
lua_createtable(ctx, 0, 3); lua_pushstring(ctx, "__index"); lua_pushlightuserdata(ctx, reinterpret_cast<void*>(&xRead)); lua_pushcclosure(ctx, &wrapped_signature_1, 1); lua_settable(ctx, -3); lua_pushstring(ctx, "__newindex"); lua_pushlightuserdata(ctx, reinterpret_cast<void*>(&xWrite)); lua_pushcclosure(ctx, &wrapped_signature_2, 1); lua_settable(ctx, -3); lua_pushstring(ctx, "__gc"); lua_pushlightuserdata(ctx, reinterpret_cast<void*>(&xDestroy)); lua_pushcclosure(ctx, &wrapped_signature_3, 1); lua_settable(ctx, -3); lua_setmetatable(ctx, x);
. - , : , cast
, .
. LUAPP_USERDATA
. , , . , registry
-, :
LUAPP_USERDATA(MyType, "MyType Lua ID") Retval setup(Context& ctx) { ctx.mt<MyType>() = Table::records(ctx);
Lua . , , «» , â .
Lua , Lua . Lua API++ placement new , , . POD-. , , .
. , -, , . , Lua , :
#include <vector> using dvec = std::vector<double>; // LUAPP_USERDATA(dvec, "Number array") // dvec aCreate(size_t size) // . { // - . return dvec(size); // RVO } void aDestroy(dvec& self) // - . { self.~dvec(); } void aWrite(dvec& self, size_t index, double val) // __newindex { self.at(index) = val; // at, Lua } Retval setup(Context& c) { // c.mt<dvec>() = Table::records(c, // "__index", static_cast<double& (dvec::*)(size_t)> (&dvec::at), // at // (const -const), "__newindex", aWrite, "__len", dvec::size, // size vector , "__gc", aDestroy ); c.global["createArray"] = aCreate; // return c.ret(); }
ãããã«
, Lua . Lua API ++, . Lua Lua API (coroutine, string buffers, ).
, Lua API, Lua. inline
, Lua API , , Link time code generation (LTO GCC). header-only. inline
Lua.
, C++11 , Lua STL. Boost Unit Test Framework .
Lua 5.2 ( 5.3 ), 5.1, LuaJIT.
Lua API++ MIT â , Lua, . HTML, .
, - .