ì§‘ì„ ì‚¬ì§€ ë§ê³ ì´ì›ƒì„ 사ë¼. â€•ìœ ëŸ½ ì†ë‹´
 * 5.0ì—서는 테그 메소드가 ì—†ì–´ì§€ê³ ë©”íƒ€í…Œì´ë¸”ì´ë¼ëŠ” ê°œë…ì„ ë‘는 등, ì™ ë§Œí•œ ëª¨ë“ ì œì–´ë¥¼ í…Œì´ë¸” 위주로 ë§Œë“¤ì–´ë²„ë ¸ìŠµë‹ˆë‹¤. ì–´ì¨Œë“ ê³µë¶€ì‚¼ì•„ 다시 번ì—해봅니다.
- íìŒ, ì´ì „ê³¼ì˜ í˜¸í™˜ì„ ìœ„í•´ lua_getglobal() 함수 ê°™ì€ ê²ƒë“¤ì´ ëª¨ë‘ ë§¤í¬ë¡œë¡œ ë§Œë“¤ì–´ì ¸ 있군요. ì´ ë§¤í¬ë¡œë¥¼ 사용해서 C 소스ìƒì—서 루아 함수를 호출하는 예는 ì›ë³¸ì—는 없지만 ì œê°€ 한번 추가해보았습니다. "Cì—서 루아 함수를 호출하기"를 ì°¸ê³ í•˜ì„¸ìš”.
- 메뉴얼 ì „ì²´ê°€ 아닌 중간 4장만 번ì—한 것입니다. (어디어디 참조)ë¼ê³ ì ì€ ë¶€ë¶„ì€ ì „ì²´ 메뉴얼ì—ì„œì˜ ì´ì•¼ê¸°ìž…니다.
- ì§ì ‘ 소스를 컴파ì¼í•´ì„œ ì •ì lib로 만들어쓰는 ê²ƒì´ íŽ¸í•˜ë‹¤ëŠ” ê²ƒì„ ìš”ì¦˜ ëŠë¼ê³ 있습니다. êµ³ì´ ë°°í¬ë³¸ ì˜ì‹í• 필요없ë”êµ°ìš”.
- 루아 5.0 알파 소스 :
http://www.lua.org/ftp/lua-5.0-alpha.tar.gz
- ì¼ë¶€ë¥¼ 번ì—해서 ë‚´ìš©ì„ ì´ë©”ì¼ë¡œ 보내주ì‹
안성규님께 ê°ì‚¬ë¥¼ 드립니다.
Contents
- 1 개요
- 2 State
- 3 ì“°ë ˆë“œ
- 4 Stackê³¼ ì¸ë±ìФ
- 5 ìŠ¤íƒ ê´€ë¦¬
- 6 스íƒì— 질ì˜í•˜ê¸°
- 7 스íƒìœ¼ë¡œë¶€í„° ê°’ì„ ì–»ì–´ë‚´ê¸°
- 8 스íƒìœ¼ë¡œ ê°’ì„ push 하기
- 9 개비지 ì»¬ëž™ì…˜ì„ ì¡°ì ˆí•˜ê¸°
- 10 ìœ ì €ë°ì´íƒ€ 루아 타입
- 11 메타테ì´ë¸”
- 12 루아 ì²í¬ë¥¼ 로딩하기
- 13 í…Œì´ë¸” 관리
- 14 ì „ì— ë³€ìˆ˜ í…Œì´ë¸”ì„ ê´€ë¦¬í•˜ê¸°
- 15 í…Œì´ë¸”ì€ ë°°ì—´ë¡œì¨ ì‚¬ìš©í•˜ê¸°
- 16 Cì—서 루아 함수를 호출하기
- 17 Protected Calls
- 18 C 함수를 ë£¨ì•„ì— ë“±ë¡í•˜ê¸°
- 19 Defining C Closures
- 19.1 Registry
1 개요 #
ì´ ì„¹ì…˜ì€ ë£¨ì•„ì˜ API(다시ë§í•˜ë©´, 호스트 프로그램ì—서 루아와 í†µì‹ í•˜ê¸° 위한 ìš©ë„로 ì œìž‘ëœ C í•¨ìˆ˜ë“¤ì˜ ëª¨ìŒ)ì— ëŒ€í•´ì„œ ì„¤ëª…í•˜ê³ ìžˆë‹¤. ëª¨ë“ API 함수와 ê´€ë ¨ëœ íƒ€ìž… ë° ìƒìˆ˜ì •ì˜ë“¤ì€ lua.h í—¤ë”í™”ì¼ì— ì •ì˜ë˜ì–´ìžˆë‹¤.
우리가 "함수"ë¼ëŠ” 용어를 사용하ë”ë¼ë„, APIë‚´ì˜ ëª‡ëª‡ êµ¬í˜„ì€ ë§¤í¬ë¡œë¡œ ì œê³µë ìˆ˜ë„ ìžˆë‹¤. ì´ëŸ¬í•œ ë©”í¬ë¡œë“¤ì€ ê° ì¸ìžë“¤ì„ ì‹¤ì œë¡œ 한번씩만 사용하며(첫번째ì¸ìžëŠ” 예외ì´ë‹¤. 왜ëƒë©´ 루아 stateì´ë¯€ë¡œ ì´ê²ƒì€ 여러번 사용ë 수 있다.), ë”°ë¼ì„œ 숨겨진 부수ì ì¸ íš¨ê³¼ë¥¼ ì¼ìœ¼í‚¤ì§€ 않는다.
2 State #
루아 ë¼ì´ë¸ŒëŸ¬ë¦¬ëŠ” ì–¸ì œë‚˜ ìž¬ì§„ìž…ì´ ê°€ëŠ¥í•˜ë‹¤ : ì´ê²ƒì€ ë¼ì´ë¸ŒëŸ¬ë¦¬ê°€ ì „ì—ë³€ìˆ˜ë“¤ì„ ê°€ì§€ê³ ìžˆì§€ 않다는 ê²ƒì„ ì˜ë¯¸í•œë‹¤. 루아 ì¸í„°í”„ë¦¬í„°ì˜ ì „ì²´ ì„¤ì • ìƒíƒœ(ì „ì— ë³€ìˆ˜ë“¤, 스íƒë“±ë“±)ì€ lua_Stateë¼ê³ 하는 ë™ì 으로 í• ë‹¹ëœ êµ¬ì¡°ì²´ì— ë‹´ê²¨ì§„ë‹¤. ì´ state는 루아 ë¼ì´ë¸ŒëŸ¬ë¦¬ì˜ ëª¨ë“ í•¨ìˆ˜ì˜ ì²«ì§¸ ì¸ìžë¡œ 넘겨지게 ëœë‹¤. (lua_open() 함수는 ì œì™¸)
루아 ë¼ì´ë¸ŒëŸ¬ë¦¬ë¥¼ 사용하기 가장 처ìŒì— 반드시 state를 ìƒì„±í•´ì•¼í•˜ëŠ”ë°, ë‹¤ìŒ í•¨ìˆ˜ë¥¼ 호출하여 ìˆ˜í–‰í• ìˆ˜ 있다.
lua_State *lua_open (void);
충분히 루아를 ì‚¬ìš©í•˜ê³ ì´ì œ ìƒì„±í•œ state를 í•´ì œí• ë•Œì—는 ë‹¤ìŒ í•¨ìˆ˜ë¥¼ 사용한다.
void lua_close (lua_State *L);
ì´ í•¨ìˆ˜ëŠ” 주어진 루아 state í™˜ê²½ë‚´ì˜ ëª¨ë“ ê°ì²´ë¥¼ 소멸시킨다. (ì•Œë§žì€ ê°œë¹„ì§€ 컬랙션 ë©”íƒ€ë©”ì†Œë“œë“¤ì„ í˜¸ì¶œí•¨ìœ¼ë¡œì¨ ì´ê²ƒì„ 수행한다.) ê·¸ë¦¬ê³ state를 ì‚¬ìš©í•˜ëŠ”ë° í• ë‹¹ëœ ëª¨ë“ ë™ì 메모리를 í•´ì œí•œë‹¤. ì¼ë°˜ì 으로, ì´ í•¨ìˆ˜ëŠ” í˜¸ì¶œí• í•„ìš”ê°€ 없다. 왜ëƒí•˜ë©´, ëª¨ë“ ë¦¬ì†ŒìŠ¤ëŠ” ì›ëž˜ì˜ 호스트 í”„ë¡œê·¸ëž¨ì´ ì¢…ë£Œí• ë•Œ 반환ë˜ê³ í•´ì œë˜ëŠ” ê²ƒì¸ ì›ì¹™ì´ë¯€ë¡œ 프로그램 종료가 확실하다면 ì´ í•¨ìˆ˜ëŠ” 사용하지 ì•Šì•„ë„ ëœë‹¤. 하지만, 오랫ë™ì•ˆ 실행ë˜ëŠ” 프로그램(웹서버와 ê°™ì€ ë°ëª¬í”„로그램과 ê°™ì€)ì€ ë©”ëª¨ë¦¬ë¥¼ ì•„ë¼ê¸° 위해서ë¼ë“ ê°€ 여러가지 ì´ìœ 로 ì¤‘ê°„ì— state를 í•´ì œí• ìˆ˜ë„ ìžˆì„ ê²ƒì´ë‹¤. lua_open() 함수를 ì œì™¸í•˜ê³ ë£¨ì•„ APIì˜ ëª¨ë“ í•¨ìˆ˜ëŠ” 첫번째 ì¸ìžë¡œ state를 요구한다.
3 ì“°ë ˆë“œ #
루아는 다중 ì“°ë ˆë“œ ì‹¤í–‰ì— ëŒ€í•œ 부분ì ì¸ ì§€ì›ì„ ì œê³µí•œë‹¤. 만약 ë©€í‹°ì“°ë ˆë”©ì„ ì§€ì›í•˜ëŠ” C ë¼ì´ë¸ŒëŸ¬ë¦¬ë¥¼ ê°€ì§€ê³ ìžˆë‹¤ë©´, 루아는 ë£¨ì•„ë‚´ë¶€ì˜ ë™ë“±í•œ 설비를 구현하기 위해 ê·¸ ë¼ì´ë¸ŒëŸ¬ë¦¬ì™€ í˜‘ë ¥í• ìˆ˜ 있다. (If you have a C library that offers multi-threading, then Lua can cooperate with it to implement the equivalent facility in Lua.) ë˜í•œ 루아는 ì“°ë ˆë“œì˜ ìƒìœ„ì—서 ìžê¸°ìžì‹ ì˜ ë³´ì¡°ë£¨í‹´ì„ êµ¬í˜„í•œë‹¤. ë‹¤ìŒ í•¨ìˆ˜ëŠ” ë£¨ì•„ë‚´ì— ìƒˆë¡œìš´ ì“°ë ˆë“œë¥¼ ìƒì„±í•œë‹¤.
lua_State *lua_newthread (lua_State *L);
ì´ í•¨ìˆ˜ëŠ” 새로운 stateê°€ 반환한다. ì´ state는 ëª¨ë“ ì „ì— í™˜ê²½(í…Œì´ë¸”등등)ì€ ê³µìœ í•˜ì§€ë§Œ ë…립ì ì¸ ì‹¤ì‹œê°„ 스íƒì„ ê°€ì§€ê³ ìžˆë‹¤. (ì´ì™€ ê°™ì€ ë‹¤ì¤‘ 스íƒì˜ ì‚¬ìš©ì€ ë°˜ë“œì‹œ C와 함께 "ë™ê¸°í™” ë˜ì–´ì•¼ 한다". How to explain that? TO BE WRITTEN.) ê° ì“°ë ˆë“œëŠ” ì „ì—변수를 위한 ë…립ì ì¸ í…Œì´ë¸”ì„ ê°€ì§€ê³ ìžˆë‹¤. ì“°ë ˆë“œë¥¼ ìƒì„±í•˜ë©´, ì´ í…Œì´ë¸”ì€ ì¸ìžë¡œ 주어진 state와 ë™ì¼í•˜ë‹¤. 그러나 ìƒì„±ëœ ì´í›„ì—는 ê·¸ ë‚´ìš©ì€ ë…립ì 으로 ë³€í• ìˆ˜ 있다. (ì—주 : 호스트ì—서 ë©€í‹°ì“°ë ˆë“œ 프로그래ë°ì„ í• ë•Œ 별ë„ì˜ ì“°ë ˆë“œë¥¼ ìƒì„±í•˜ê³ , ì“°ë ˆë“œê°€ 소멸ë˜ë©´ 차후 병합하는 ê¸°ëŠ¥ì„ í•˜ëŠ” 것으로 추측ë¨. ì•„ì§ì€ 불안한 ëŠë‚Œì´...-_-;)
ìƒì„±í•œ ì“°ë ˆë“œëŠ” ë‹¤ìŒ í•¨ìˆ˜ë¡œ 없앨 수 있다.
void lua_closethread (lua_State *L, lua_State *thread);
맨 ë§ˆì§€ë§‰ì˜ stateì— ëŒ€í•œ ì“°ë ˆë“œëŠ” ì´ í•¨ìˆ˜ë¡œ 닫으면 안ëœë‹¤. ëŒ€ì‹ ì—, 마지막 ì“°ë ˆë“œ state는 lua_close()를 사용하여 í•´ì œí•˜ë¼.
4 Stackê³¼ ì¸ë±ìФ #
루아는 C 함수로부터 ê°’ë“¤ì„ ë„˜ê²¨ë°›ê¸° 위해 ê°€ìƒì˜ 스íƒì„ 사용한다. ì´ ìŠ¤íƒì•ˆì˜ ê°ê°ì˜ 요소는 루아 값으로 표현ëœë‹¤.(nil, number, string, 등등)
ê°ê°ì˜ C í•¨ìˆ˜ì˜ ì‹¤í–‰ì€ (ê°€ìƒì 으로) ê°ìžì˜ 스íƒì„ ê°€ì§€ê³ ìžˆë‹¤. 루아가 C 함수를 í˜¸ì¶œí• ë•Œë§ˆë‹¤, í˜¸ì¶œëœ í•¨ìˆ˜ëŠ” 새로운 스íƒì„ 얻게 ëœë‹¤.(ì´ ìŠ¤íƒì€ ì´ì „ì˜ ìŠ¤íƒ í˜¹ì€ í™œì„±í™” ìƒíƒœì¸ C í•¨ìˆ˜ë“¤ì˜ ìŠ¤íƒë“¤ì™€ëŠ” ë…립ì ì´ë‹¤)
편ì˜ìƒ, APIë‚´ì˜ ëŒ€ë¶€ë¶„ì˜ ì§ˆì˜ í˜•ì‹ì˜ ëª…ë ¹ë“¤ì€ ì—„ê²©í•œ ìŠ¤íƒ ì›ì¹™ì„ 따르지 않는다. ëŒ€ì‹ ì—, ì´ë“¤ì€ ì¸ë±ìŠ¤ë¥¼ 사용하는 ê²ƒì— ì˜í•´ 스íƒì˜ ê° ìš”ì†Œë¥¼ 참조하는 ê²ƒì´ ê°€ëŠ¥í•˜ë‹¤. ì–‘ìˆ˜ê°’ì˜ ì¸ë±ìŠ¤ëŠ” 스íƒìƒì˜ ì ˆëŒ€ 위치를 ì˜ë¯¸í•œë‹¤. (1부터 시작한다) ìŒìˆ˜ê°’ì˜ ì¸ë±ìŠ¤ëŠ” 스íƒì˜ topì—ì„œë¶€í„°ì˜ offsetì„ ë‚˜íƒ€ë‚¸ë‹¤. ì¢€ë” ëª…í™•í•˜ê²Œ ë§í•˜ìžë©´, 만약 스íƒì´ nê°œì˜ ìš”ì†Œë¥¼ ê°€ì§€ê³ ìžˆë‹¤ë©´, ì¸ë±ìФ 1ì€ ê°€ìž¥ ì²˜ìŒ ìš”ì†Œë¥¼ 나타낸다.(다시 ë§í•˜ë©´, 스íƒì— ë§¨ì²˜ìŒ í‘¸ì‰¬ëœ ìš”ì†Œë¥¼ ì˜ë¯¸í•œë‹¤) ê·¸ë¦¬ê³ ì¸ë±ìФ nì€ ê°€ìž¥ 마지막 요소를 ì˜ë¯¸í•œë‹¤. -1 ì¸ë±ìŠ¤ëŠ” 가장 마지막 ì¸ë±ìŠ¤ë¥¼ 나타낸다. (다시ë§í•˜ìžë©´, top ìœ„ì¹˜ì˜ ìš”ì†Œë¥¼ 가리틴다.) ê·¸ë¦¬ê³ -n ì¸ë±ìŠ¤ëŠ” 첫번째 ì¸ë±ìŠ¤ë¥¼ 나타낸다. ë‚´ë¶€ì 으로 ì¸ë±ìŠ¤ê°€ ì 법한지를 검사하는 ì¡°ê±´ì€ ì¸ë±ìФ ê°’ì´ 1ê³¼ 스íƒì˜ top사ì´ì— 놓여있는지 여부ì´ë‹¤. (다시ë§í•˜ë©´, 1 <= abs(ì¸ë±ìФ) <= top)
코드ìƒì˜ ì–¸ì œë¼ë„, ë‹¤ìŒ í•¨ìˆ˜ë¥¼ 호출하여 top ìš”ì†Œì˜ ì¸ë±ìŠ¤ë¥¼ ì–»ì„ ìˆ˜ 있다.
int lua_gettop (lua_State *L);
ì¸ë±ìŠ¤ê°€ 1부터 시작하기 때문ì—, lua_gettop() í•¨ìˆ˜ì˜ ë°˜í™˜ê°’ì€ ìŠ¤íƒì•ˆì— í‘¸ì‰¬ëœ ìš”ì†Œì˜ ìˆ˜ì™€ 같다. (그러므로 0ì´ ë°˜í™˜ë˜ì—ˆë‹¤ë©´ 스íƒì´ 비었다는 ëœ»ì´ ëœë‹¤.)
루아 API를 ì‚¬ìš©í•˜ëŠ”ë° ìžˆì–´ì„œ, ì—¬ëŸ¬ë¶„ì€ ìŠ¤íƒ ì˜¤ë²„í”Œë¡œìš°ë¥¼ ê²€ì‚¬í• ì±…ìž„ì´ ìžˆë‹¤. ë‹¤ìŒ í•¨ìˆ˜ë¥¼ 사용하여 검사한다.
int lua_checkstack (lua_State *L, int extra);
ì´ í•¨ìˆ˜ë¥¼ 실행하면 스íƒí¬ê¸°ê°€ top + extraê°’ë§Œí¼ ì¦ê°€í•˜ê²Œ ëœë‹¤. 만약 ì§€ì •í•œ extraë§Œí¼ ì¦ê°€í•˜ì§€ 못한다면 false를 반환한다. ì´ í•¨ìˆ˜ëŠ” ì ˆëŒ€ë¡œ 스íƒê³µê°„ì„ ì¤„ì–´ë“¤ê²Œ 하지 않는다. 만약 스íƒì´ ì´ë¯¸ 새로운 í¬ê¸°ë³´ë‹¤ í¬ë‹¤ë©´, 변경ë˜ì§€ ì•Šì€ ì±„ë¡œ ìœ ì§€ëœë‹¤.
루아가 C 함수를 í˜¸ì¶œí• ë•ŒëŠ” ì–¸ì œë¼ë„, lua_checkstack(L, LUA_MINSTACK)ì˜ ê²°ê³¼ê°€ trueì¸ ê²ƒì„ ë³´ìž¥í•œë‹¤. 다시ë§í•˜ë©´, ì ì–´ë„ LUA_MINSTACK 위치가 ì•„ì§ ì‚¬ìš©ê°€ëŠ¥í•˜ë‹¤ëŠ” 뜻ì´ë‹¤. LUA_MINSTACKì€ lua.hì— 20으로 ì •ì˜ë˜ì–´ 있으며, ì‹¤ì œ 코드ì—서 ë°˜ë³µë¬¸ì„ ì‚¬ìš©í•˜ì—¬ 스íƒì— ê°’ì„ í‘¸ì‰¬í•˜ì§€ 않는다면 ìŠ¤íƒ í¬ê¸°ì— 대해서는 ì¼ë°˜ì 으로 ê±±ì •í• í•„ìš”ê°€ 없다.
ëŒ€ë¶€ë¶„ì˜ ì§ˆì˜ í•¨ìˆ˜ë“¤ì€ í—ˆìš©ëœ ìŠ¤íƒ ê³µê°„ë‚´ì˜ ê°’ë§Œ ì¸ë±ìŠ¤ë¡œì¨ ë°›ì•„ë“¤ì¸ë‹¤. 다시ë§í•˜ë©´, 최대 ìŠ¤íƒ í¬ê¸°ë¥¼ 초과하는 ì¸ë±ìŠ¤ë“¤ì€ lua_checkstack() 함수를 사용하여 ì„¤ì •í•´ì•¼í•œë‹¤. ì´ì™€ ê°™ì€ ì¸ë±ìŠ¤ë“¤ì€ "허용가능한 ì¸ë±ìФ"ë¼ê³ 부르기로 한다. ì¢€ë” ì •í˜•ì 으로 ë§í•œë‹¤ë©´, 우리는 "허용가능한 ì¸ë±ìФ"를 다ìŒê³¼ ê°™ì´ ì •ì˜í• 수 있다.
(index < 0 && abs(ì¸ë±ìФ) <= top) || (ì¸ë±ìФ > 0 && ì¸ë±ìФ <= top + stackspace)
0 ì¸ë±ìŠ¤ëŠ” ì ˆëŒ€ë¡œ ì ‘ê·¼ì´ ë¶ˆê°€ëŠ¥í•œ ì¸ë±ìФë¼ëŠ” ì ì— ì£¼ì˜í•˜ë¼. Unless otherwise noticed, any function that accepts valid indices can also be called with pseudo-indices, which represent some Lua values that are accessible to the C code but are not in the stack. 가짜 ì¸ë±ìŠ¤ëŠ” ì „ì—변수테ì´ë¸”(4.13장 참조), 래지스트리, C í•¨ìˆ˜ì˜ upvalueë“¤ì„ ì–µì„¸ìŠ¤í•˜ëŠ”ë° ì‚¬ìš©ëœë‹¤.
5 ìŠ¤íƒ ê´€ë¦¬ #
루아 API는 기본ì ì¸ ìŠ¤íƒê´€ë¦¬ë¥¼ 위해 ë‹¤ìŒ í•¨ìˆ˜ë“¤ì„ ì œê³µí•œë‹¤.
void lua_settop (lua_State *L, int index); void lua_pushvalue (lua_State *L, int index); void lua_remove (lua_State *L, int index); void lua_insert (lua_State *L, int index); void lua_replace (lua_State *L, int index);
lua_settop()ì€ 0 ë˜ëŠ” 사용가능한 ì¸ë±ìŠ¤ë¥¼ 받아서 스íƒì˜ top으로 ì„¤ì •í•œë‹¤. 만약 새로운 topì´ ì§€ì •í•˜ê¸° ì „ë³´ë‹¤ í¬ë‹¤ë©´, 늘어난 ë§Œí¼ì˜ 스íƒê³µê°„ì€ nil로 채워지게 ëœë‹¤. 만약 ì¸ë±ìŠ¤ê°€ 0ì´ë©´ ëª¨ë“ ìŠ¤íƒ ìš”ì†ŒëŠ” ì œê±°ëœë‹¤. lua.hì— ë‹¤ìŒê³¼ ê°™ì€ ì“¸ë§Œí•œ 매í¬ë¡œê°€ ì •ì˜ë˜ì–´ìžˆë‹¤. ì´ê²ƒì€ nê°œë§Œí¼ ìŠ¤íƒìœ¼ë¡œë¶€í„° pop처리를 수행한다.
#define lua_pop(L,n) lua_settop(L, -(n)-1)
lua_pushvalue() 함수는 주어진 ì¸ë±ìФìƒì˜ ê°’ì˜ ë³µì‚¬ë³¸ì„ ìŠ¤íƒì— 푸쉬 처리한다. lua_remove()는 ì§€ì •í•œ ì¸ë±ìФ ìœ„ì¹˜ì˜ ê°’ì„ ì œê±°í•˜ê³ , 지워진 ê³³ì„ ë§¤ê¾¸ê¸°ìœ„í•´ 나머지 ìœ„ì¹˜ì˜ ìš”ì†Œë“¤ì„ ëª¨ë‘ ëŒì–´ì˜¬ë¦°ë‹¤. (다시ë§í•˜ë©´, 주어진 ìœ„ì¹˜ì˜ ê°’ë§Œ 빼낸다.) lua_replace()는 ê° ìš”ì†Œë“¤ì˜ ìœ„ì¹˜ì´ë™ì—†ì´ 주어진 ì¸ë±ìФ 위치로 top ìš”ì†Œì˜ ê°’ì„ ì´ë™ì‹œí‚¨ë‹¤. (ì´ê²ƒì€ topì˜ ê°’ì„ ì£¼ì–´ì§„ 위치로 ë®ì–´ì“°ê³ , pop처리한 것과 같다.) ì´ í•¨ìˆ˜ë“¤ì€ ë°˜ë“œì‹œ ì 법한 ì¸ë±ìŠ¤ë§Œì„ ë°›ì•„ë“¤ì¸ë‹¤. (확실하게 하ìžë©´, 가짜 ì¸ë±ìŠ¤ë¥¼ ê°€ì§€ê³ lua_remove나 lua_insert를 í˜¸ì¶œí• ìˆ˜ 없다. 가짜ì¸ë±ìŠ¤ëŠ” ì‹¤ì œ 스íƒìƒì˜ 위치를 나타내지 않기 때문ì´ë‹¤.)
아래 예ì—서는 10 20 30 40 50*ê³¼ ê°™ì´ ìŠ¤íƒì´ ìžˆë‹¤ê³ ê°€ì •í•˜ê³ í•¨ìˆ˜ë“¤ì„ ì 용한 것ì´ë‹¤. (바닥ì—서 top까지 순서대로 나열한 것ì´ë©° * 표시가 topì„ ì˜ë¯¸í•œë‹¤)
lua_pushvalue(L, 3) --> 10 20 30 40 50 30* lua_pushvalue(L, -1) --> 10 20 30 40 50 30 30* lua_remove(L, -3) --> 10 20 30 40 30 30* lua_remove(L, 6) --> 10 20 30 40 30* lua_insert(L, 1) --> 30 10 20 30 40* lua_insert(L, -1) --> 30 10 20 30 40* (no effect) lua_replace(L, 2) --> 30 40 20 30* lua_settop(L, -3) --> 30 40 20* lua_settop(L, 6) --> 30 40 20 nil nil nil*
6 스íƒì— 질ì˜í•˜ê¸° #
ìŠ¤íƒ ìš”ì†Œê°’ì˜ íƒ€ìž…ì„ ê²€ì‚¬í•˜ê¸° 위해서 다ìŒê³¼ ê°™ì€ í•¨ìˆ˜ë“¤ì´ ì œê³µëœë‹¤.
int lua_type (lua_State *L, int index); int lua_isnil (lua_State *L, int index); int lua_isboolean (lua_State *L, int index); int lua_isnumber (lua_State *L, int index); int lua_isstring (lua_State *L, int index); int lua_istable (lua_State *L, int index); int lua_isfunction (lua_State *L, int index); int lua_iscfunction (lua_State *L, int index); int lua_isuserdata (lua_State *L, int index); int lua_isdataval (lua_State *L, int index);
ì´ í•¨ìˆ˜ë“¤ì€ ì‚¬ìš©ê°€ëŠ¥í•œ ì¸ë±ìŠ¤ë¥¼ 사용하여 호출ë 수 있다. lua_type() 함수는 해당 ì¸ë±ìФìƒì˜ ê°’ì˜ íƒ€ìž…ì„ ë°˜í™˜í•œë‹¤. LUA_TNONEì€ ì 법하지 ì•Šì€ ì¸ë±ìФë¼ëŠ” ì˜ë¯¸ì´ë©°(다시ë§í•˜ë©´, 스íƒì˜ ìƒíƒœê°€ 비어있는 ìƒíƒœì¼ ê²½ìš°ë„ ë“¤ 수 있다.) lua.hì— ë‹¤ìŒê³¼ ê°™ì´ íƒ€ìž…ì— ë”°ë¥¸ ìƒìˆ˜ë“¤ì´ ì •ì˜ë˜ì–´ìžˆë‹¤ : LUA_TNIL, LUA_TNUMBER, LUA_TBOOLEAN, LUA_TSTRING, LUA_TTABLE, LUA_TFUNCTION, LUA_TUSERDATA, LUA_TLIGHTUSERDATA. ë‹¤ìŒ í•¨ìˆ˜ëŠ” ê° ìƒìˆ˜ë¥¼ íƒ€ìž…ëª…ì„ ë‚˜íƒ€ë‚´ëŠ” 문ìžì—´ë¡œ 번ì—해준다.
const char *lua_typename (lua_State *L, int type);
lua_is...으로 시작하는 í•¨ìˆ˜ë“¤ì€ ë§Œì•½ 주어진 타입과 호환ëœë‹¤ë©´ 1ì„ ë°˜í™˜í•˜ë©°, 아니면 0ì„ ë°˜í™˜í•œë‹¤. lua_isboolean() 함수는 ì´ ì›ì¹™ì—서 예외ì´ë‹¤. ì´ í•¨ìˆ˜ëŠ” 단지 boolean ê°’ì—ë§Œ 사용ëœë‹¤. (ê·¸ë ‡ì§€ 않으면 ì´ í•¨ìˆ˜ëŠ” 쓸모가 ì—†ì„ì§€ë„ ëª¨ë¥¸ë‹¤. booleanê³¼ 호환ë˜ëŠ” ê°’ì€ ì—†ë‹¤.) ì 법하지 ì•Šì€ ì¸ë±ìŠ¤ë¥¼ 사용하면 ì–¸ì œë‚˜ ì´ í•¨ìˆ˜ë“¤ì€ 0ì„ ë°˜í™˜í•œë‹¤. lua_isnumber() 함수는 숫ìžë‚˜ 숫ìžë¡œë§Œ ì´ë£¨ì–´ì§„ 문ìžì—´ì„ 받아들ì´ë©°, lua_isstring()ì€ ë¬¸ìžì—´ê³¼ 숫ìžë“¤ì„ 받아들ì¸ë‹¤. lua_isfunction()ì€ ë£¨ì•„ 함수와 C 함수 ì–‘ìª½ì„ ë°›ì•„ë“¤ì¸ë‹¤. 루아 함수ì¸ì§€ C 함수ì¸ì§€ë¥¼ êµ¬ë³„í•˜ë ¤ë©´ lua_iscfunction() 를 사용하ë¼. 숫ìžì¸ì§€ 숫ìžë¡œ ì´ë£¨ì–´ì§„ 문ìžì—´ì¸ì§€ë¥¼ êµ¬ë³„í•˜ë ¤ë©´ lua_type() 함수를 사용하면 ëœë‹¤.
API는 ë˜í•œ 스íƒìƒì˜ ë‘ ê°’ë“¤ì„ ë¹„êµí•˜ê¸° 위한 í•¨ìˆ˜ë“¤ì„ ê°€ì§€ê³ ìžˆë‹¤.
int lua_equal (lua_State *L, int index1, int index2); int lua_lessthan (lua_State *L, int index1, int index2);
'.. 와 다르다'ë¼ë˜ê°€ '..보다 í¬ë‹¤' 비êµëŠ” 위 í•¨ìˆ˜ì˜ ìˆœì„œë§Œ 바꾸어 충분히 í• ìˆ˜ 있다. ê° í•¨ìˆ˜ë“¤ì€ ë§Œì•½ ì 법하지 ì•Šì€ ì¸ë±ìŠ¤ë¥¼ 사용했다면 0ì„ ë°˜í™˜í•œë‹¤.
7 스íƒìœ¼ë¡œë¶€í„° ê°’ì„ ì–»ì–´ë‚´ê¸° #
스íƒì— 있는 ê°’ì€ ëª…ì‹œëœ C형태로 ì „ì†¡í•˜ê¸° 위해서, ì—¬ëŸ¬ë¶„ì€ ì•„ëž˜ì˜ í•¨ìˆ˜ë“¤ì„ ì‚¬ìš©í• ìˆ˜ 있다:
int lua_toboolean (lua_State *L, int index); lua_Number lua_tonumber (lua_State *L, int index); const char *lua_tostring (lua_State *L, int index); size_t lua_strlen (lua_State *L, int index); lua_CFunction lua_tocfunction (lua_State *L, int index); void *lua_touserdata (lua_State *L, int index);
ì´ í•¨ìˆ˜ë“¤ì€ ì–´ë–¤ ë°›ì•„ë“¤ì¼ ìˆ˜ 있는 ì¸ë±ìФ ê°’ê³¼ 함께 호출ë 수 있다. 만약 ì ì ˆí•œ ì¸ë±ìФ ê°’ì´ ì£¼ì–´ì§€ì§€ 않으면 주어진 ê°’ì´ ë¶€ì •í™•í•œ íƒ€ìž…ì„ ê°€ì§„ 것으로 ë™ìž‘한다.
lua_toboolean() 함수는 주어진 ì¸ë±ìŠ¤ì— ìžˆëŠ” 루아 ê°’ì„ C불리언(0ë˜ëŠ”,1) 값으로 바꾼다. ëª¨ë“ ë£¨ì•„ì˜ í…ŒìŠ¤íŠ¸ì™€ ê°™ì´ ì–´ë–¤ ë£¨ì•„ê°’ì— ëŒ€í•˜ì—¬ 1ì„ ë¦¬í„´í•˜ê³ ì ì ˆí•œ ì¸ë±ìФ ê°’ì´ ì£¼ì–´ì§€ì§€ ì•Šì€ ê²½ìš°ì—는 0ì„ ë¦¬í„´í•œë‹¤. (만약 ì—¬ëŸ¬ë¶„ì´ ì™„ì „í•œ 불리언 ê°’ì„ ë°›ê³ ì‹¶ë‹¤ë©´ lua_isboolean함수를 ì´ìš©í•˜ì—¬ í˜•ì„ ì±„í¬í•´ ë³¼ 수 있다.)
lua_tonumber()함수는 주어진 ì¸ë±ìŠ¤ì˜ ê°’ì€ ìˆ«ìžë¡œ 바꿔준다(lua_Numberì˜ ê¸°ë³¸ê°’ì€ doubleì´ë‹¤). 루아 변수는 숫ìžì´ê±°ë‚˜ 변환가능한 숫ìžë¡œ ë˜ì–´ 있는 문ìžì—´ì´ë‹¤. (2.4ì ˆì„ ë³´ê¸° 바란다.) ê¸°íƒ€ì˜ ê²½ìš°ëŠ” 0ì„ ë¦¬í„´í•œë‹¤.
lua_tostring() 함수는 주어진 ì¸ë±ìŠ¤ì˜ ê°’ì„ ë¬¸ìžì—´(const char*)로 변환해준다. 루아 변수는 문ìžì—´ì´ê±°ë‚˜ 숫ìžì—¬ì•¼ 한다. 다른 경우는 함수가 NULLì„ ë¦¬í„´í•œë‹¤. ë§Œì•½ì— ë£¨ì•„ 변수가 숫ìž(number)ì¸ ê²½ìš° 스íƒì˜ ê°’ì„ ë¬¸ìžì—´ë¡œ 변환해준다. lua_tostring()함수는 ì™„ì „ížˆ ì •ë ¬ëœ ë£¨ì•„ 환경 안ì—ì„œì˜ ë¬¸ìžì—´ì„ 리턴한다.(This change confuses lua_next when lua_tostring is applied to keys.) ì´ ë¬¸ìžì—´ì€ C처럼 í•ìƒ ëì— \0를 ê°€ì§€ê³ ìžˆë‹¤. 하지만 ì¤‘ê°„ì— \0를 ê°€ì§€ê³ ìžˆì„ ìˆ˜ë„ ìžˆë‹¤. ë§Œì•½ì— ì¤‘ê°„ì— \0를 ê°€ì§€ê³ ìžˆë‹¤ëŠ” ê²ƒì„ ëª¨ë¥¸ë‹¤ë©´, lua_strlen()함수를 ì´ìš©í•˜ì—¬ 실재 길ì´ë¥¼ 재 ë³¼ 수 있다. 루아는 개비지 컬ëŸì…˜ì„ 하기 때문 lua_tostringì— ì˜í•´ 얻어진 í¬ì–¸í„°ê°€ 나중ì—ë„ ìœ íš¨í•˜ì§€ëŠ” 않다. 그래서 ë§Œì•½ì— í•¨ìˆ˜ë¥¼ 호출해서 스트ë§ì„ 넘겨 받았다면 ì´ê²ƒì„ 보사해 ë‘ì–´ì—¬ 한다. (í˜¹ì€ ëž˜ì§€ìŠ¤íŠ¸ë¦¬ì— ë“±ë¡í•˜ëŠ” ë°©ë²•ì´ ìžˆë‹¤. (4.8ì ˆì„ ì°¸ì¡°) )
lua_tocfunction() 함수는 스í…ì˜ C함수는 변수로 바꿔준다. ì´ í•¨ìˆ˜ëŠ” C함수여야 한다. 다른 경우는 NULLì„ ë°˜í™˜í•œë‹¤. lua_CFunction í˜•ì— ê´€í•œ ë‚´ìš©ì€ 4.17ì ˆì— ë‚˜ì™€ìžˆë‹¤.
lua_touserdata() 함수는 4.9ì ˆì„ ì°¸ì¡°í•œë‹¤.
8 스íƒìœ¼ë¡œ ê°’ì„ push 하기 #
C ë³€ìˆ˜ê°’ì„ ìŠ¤íƒì— push하기 위해 API는 ì•„ëž˜ì˜ í•¨ìˆ˜ë“¤ì„ ê°€ì§€ê³ ìžˆë‹¤ :
void lua_pushboolean (lua_State *L, int b); void lua_pushnumber (lua_State *L, lua_Number n); void lua_pushlstring (lua_State *L, const char *s, size_t len); void lua_pushstring (lua_State *L, const char *s); void lua_pushnil (lua_State *L); void lua_pushcfunction (lua_State *L, lua_CFunction f); void lua_pushlightuserdata (lua_State *L, void *p);
ì´ í•¨ìˆ˜ë“¤ì€ C ë³€ìˆ˜ê°’ì„ ë°›ì•„ì„œ 루아 값으로 바꿔서 결과를 스íƒì— 집어넣는다. lua_pushlstring ê³¼ lua_pushstring ì˜ ê²½ìš°ì—는 주어진 문ìžì—´ì— 대하여 특별히 ë‚´ë¶€ì ì¸ ë³µì‚¬ë³¸ì„ ë§Œë“ ë‹¤. lua_pushstringì€ ì ì ˆí•œ C문ìžì—´(NULL-ended 문ìžì—´ì„ ë§í•œë‹¤.)ë§Œ 사용ëœë‹¤. ê·¸ë¦¬ê³ lua_pushlstringì˜ ê²½ìš°ì—는 í¬ê¸°ë¥¼ ëª…ì‹œí• ìˆ˜ 있다.
ê·¸ë¦¬ê³ ì—¬ëŸ¬ë¶„ì€ ë˜í•œ "í¬ë§·ëœ" 문ìžì—´ë„ ì‚¬ìš©í• ìˆ˜ 있다:
const char *lua_pushfstring (lua_State *L, const char *fmt, ...); const char *lua_pushvfstring (lua_State *L, const char *fmt, va_list argp);
ì´ ë‘ í•¨ìˆ˜ëŠ” 문ìžì—´ì˜ 형ì‹ì„ ë§Œë“ ë‹¤ìŒì— 만들어진 문ìžì—´ì˜ í¬ì¸í„°ë¥¼ 스íƒì— 집어넣는다. ì´ í•¨ìˆ˜ë“¤ì€ sprintf ê·¸ë¦¬ê³ vsprintf와 ìƒë‹¹ížˆ ìœ ì‚¬í•˜ì§€ë§Œ 몇가지 중요한 ì°¨ì´ì ì´ ìžˆë‹¤.
결과를 위하여 ê³µê°„ì„ í• ë‹¹í• í•„ìš”ê°€ 없다.; 결과는 루아 문ìžì—´ì´ ë˜ê³ 루아는 ì´ ë¬¸ìžì—´ì˜ 메모리를 관리해 준다.
변환 명시ìžë“¤ì´ ì œí•œì ì´ë‹¤. 플랙ì´ë‚˜, 너비, ì •í™•ë„ ë“±ì„ ëª…ê¸°í• ìˆ˜ 없다. ì´ ë³€í™˜ 명시ìžë“¤ì€ %% (% ì— ë¬¸ìžì—´), %s (ê¸¸ì´ ì œí•œ 없는 NULL-로 ë나는 문ìžì—´), %f (lua_Number), %d (ì •ìˆ˜), %c (문ìž)ê°€ 있다.
9 개비지 ì»¬ëž™ì…˜ì„ ì¡°ì ˆí•˜ê¸° #
Lua uses two numbers to control its garbage collection: the count and the threshold (see Section 2.6). The first counts the ammount of memory in use by Lua; when the count reaches the threshold, Lua runs its garbage collector. After the collection, the count is updated, and the threshold is set to twice the count value.
You can access the current values of these two numbers through the following functions:
int lua_getgccount (lua_State *L); int lua_getgcthreshold (lua_State *L);
Both return their respective values in Kbytes. You can change the threshold value with
void lua_setgcthreshold (lua_State *L, int newthreshold);
Again, the newthreshold value is given in Kbytes. When you call this function, Lua sets the new threshold and checks it against the byte counter. If the new threshold is smaller than the byte counter, then Lua immediately runs the garbage collector. In particular lua_setgcthreshold(L,0) forces a garbage collectiion. After the collection, a new threshold is set according to the previous rule.
10 ìœ ì €ë°ì´íƒ€ 루아 타입 #
ìœ ì €ë°ì´íƒ€ íƒ€ìž…ì€ ë£¨ì•„ë‚´ì—서 C 언어 ê°’ì„ ì˜ë¯¸í•œë‹¤. 루아는 "full"ê³¼ "light"ì˜ ë‘가지 íƒ€ìž…ì˜ ìœ ì €ë°ì´íƒ€ë¥¼ ì§€ì›í•œë‹¤.
"full" ìœ ì €ë°ì´íƒ€ëŠ” 루아 í™˜ê²½ë‚´ì— ìƒì„±ëœ ë©”ëª¨ë¦¬ì˜ ë¸”ëŸì„ ì˜ë¯¸í•œë‹¤. ì´ê²ƒì€ (í…Œì´ë¸”ê³¼ ê°™ì€) 루아 ê°ì²´ë¡œ 간주ë˜ë©° 다ìŒê³¼ ê°™ì€ íŠ¹ì§•ì„ ê°€ì§„ë‹¤.
- 루아 코드내ì—서 ìƒì„±ì´ 가능하다.
- ìžì‹ ë§Œì˜ ë©”íƒ€í…Œì´ë¸”ì„ ê°€ì§€ê³ ìžˆë‹¤. 그러므로, ê°œë¹„ì§€ì»¬ë ‰ì…˜ì´ ì‹¤í–‰ë 때를 ê°ì§€í• 수 있다.
- ìƒì„±ëœ 후ì—는 ìžê¸°ìžì‹ ë§Œì˜ ë©”ëª¨ë¦¬ 주소를 가진다. 즉, ê°ê°ì˜ ì¸ìŠ¤í„´ìŠ¤ê°€ 별ë„로 ìƒì„±ëœë‹¤.
- 루아내ì—서 ìƒì„±í• 수 없으며 ê¼ ì™¸ë¶€ì—서 넘겨주어야만 한다.
- ìžì‹ ë§Œì˜ ë©”íƒ€í…Œì´ë¸”ì„ ê°€ì§€ê³ ìžˆì§€ 않다. 루아내ì—서 ìƒì„±ë 수 없으므로 개비지 컬랙션ë˜ì§€ë„ 않는다.
- ë§Œì¼ ê°™ì€ ì£¼ì†Œìƒì— ìƒì„±ë˜ì—ˆë‹¤ë©´, ì´ê²ƒì€ 아무리 다른 ì´ë¦„ì„ ë£¨ì•„ë‚´ì— ê°€ì§„ë‹¤í•˜ë”ë¼ë„ ê°™ì€ ë‚´ìš©ì„ ê°€ì§€ê²Œ ëœë‹¤. (í¬ì¸í„°ì´ë‹ˆ 당연한 얘기.)
ë‹¤ìŒ í•¨ìˆ˜ë¥¼ 사용하여 C 코드ìƒì—서 full ìœ ì €ë°ì´íƒ€ë¥¼ ìƒì„±í• 수 있다.
void *lua_newuserdata (lua_State *L, size_t size);
ì´ í•¨ìˆ˜ëŠ” 루아 í™˜ê²½ë‚´ì— ì£¼ì–´ì§„ í¬ê¸°ë§Œí¼ 새로운 메모리블ëŸì„ í• ë‹¹í•˜ê³ , 스íƒì— ìƒì„±ëœ 블ëŸì˜ 주소를 가진 ìœ ì €ë°ì´íƒ€ë¥¼ 푸쉬한 후, ìƒì„±ëœ 블ëŸì˜ ì£¼ì†Œê°’ì„ ë°˜í™˜í•œë‹¤. light ìœ ì €ë°ì´íƒ€ë¥¼ 스íƒì— í‘¸ì‰¬í•˜ë ¤ë©´ lua_pushlightuserdata() API를 사용하면 ëœë‹¤. (4.7장 참조)
lua_touserdata() API함수(4.6장 참조)는 ìœ ì €ë°ì´íƒ€ì˜ ê°’ì„ ë°˜í™˜í•œë‹¤. full ìœ ì €ë°ì´íƒ€ìƒì— ì´ í•¨ìˆ˜ë¥¼ 사용하면, 해당 메모리 블ëŸì˜ í¬ì¸í„°ë¥¼ ë°˜í™˜í•˜ê³ , lightì— ì‚¬ìš©í•˜ë©´ ê·¸ì— í•´ë‹¹í•˜ëŠ” í¬ì¸í„°ê°’ì„ ë°˜í™˜í•œë‹¤. ìœ ì €ë°ì´íƒ€ 타입 ì´ì™¸ì˜ ê°’ì— ì´ í•¨ìˆ˜ë¥¼ 사용하면 NULLì´ ë°˜í™˜ëœë‹¤.
루아가 full ìœ ì €ë°ì´íƒ€ë¥¼ 개비지 ì»¬ëž™ì…˜ì„ ì ìš©í• ë•Œì—는 ê·¸ ìœ ì €ë°ì´íƒ€ì— 대한 gc 메타메소드를 실행하며, ê·¸ëŸ°ë‹¤ìŒ ê·¸ì— í•´ë‹¹í•˜ëŠ” 메모리를 í•´ì œí•œë‹¤. (앞서 ë§í–ˆë“¯ì´, light ìœ ì €ë°ì´íƒ€ëŠ” 개비지 컬랙션ë˜ì§€ 않는다. 그러므로 호스트 프로그램간 í†µì‹ ì— ê°€ìž¥ ìœ ìš©í•˜ê²Œ ì“°ì¼ ìˆ˜ 있다.)
11 메타테ì´ë¸” #
ë‹¤ìŒ í•¨ìˆ˜ë“¤ì€ í•´ë‹¹ ì¸ë±ìŠ¤ì˜ ê°ì²´ì— 대한 메타테ì´ë¸”ì„ ë‹¤ë£¨ê¸° 위한 것들ì´ë‹¤.
int lua_getmetatable (lua_State *L, int objindex); int lua_setmetatable (lua_State *L, int objindex);
양쪽 함수 ëª¨ë‘ ì²˜ë¦¬ë¥¼ 위한 ì 법한 indexë¡œì¨ objindex를 요구한다. lua_getmetatable() 함수는 ì§€ì •í•œ objindexì— í•´ë‹¹ë˜ëŠ” ê°ì²´ì˜ 메타테ì´ë¸”ì„ ìŠ¤íƒì— 푸쉬한다. lua_setmetatable() 함수는 현재 스íƒì˜ topìœ„ì¹˜ì— ìžˆëŠ” í…Œì´ë¸”ì„ í•´ë‹¹ ê°ì²´ë¥¼ 위한 ì‹ ê·œ 메타테ì´ë¸”로 ì„¤ì •í•œë‹¤. ê·¸ë¦¬ê³ í…Œì´ë¸”ì„ pop처리한다. 즉, ì¼ë°˜ì 으로 ì‹ ê·œ 메타테ì´ë¸”ì„ ë“±ë¡í•˜ëŠ” 코드는 다ìŒê³¼ 같다.
newuserdata = (char *) lua_newuserdata(L, userdatasize); -- ì‹ ê·œ full ìœ ì €ë°ì´íƒ€ë¥¼ ìƒì„±í•œ 후 스íƒì˜ 맨 ì•žì— í‘¸ì‰¬. lua_newtable(L); -- ì‹ ê·œ 빈 í…Œì´ë¸”ì„ ìƒì„±í•œ 후 스íƒì˜ topì— í‘¸ì‰¬. lua_setmetatable(L, -2); -- ì´ ì‹œì ì—서 ì•žì— ìƒì„±í•œ í…Œì´ë¸”ì€ newuserdataì˜ ë©”íƒ€í…Œì´ë¸”로 등ë¡ëœë‹¤. (popë˜ì–´ 없어진다.) -- ì´ì œ 스íƒì˜ topì€ newuserdataì´ë‹¤.
만약 ê°ì²´ê°€ 메타테ì´ë¸”ì„ ê°€ì§€ê³ ìžˆì§€ 않다면, lua_getmetatable() 함수는 0ì„ ë°˜í™˜í•˜ë©°, 스íƒì—는 ì•„ë¬´ê²ƒë„ í‘¸ì‰¬í•˜ì§€ 않는다. 주어진 ê°ì²´ì— 메타테ì´ë¸”ì„ ì„¤ì •í• ìˆ˜ 없는 경우(다시ë§í•˜ë©´, ê°ì²´ê°€ ìœ ì €ë°ì´íƒ€ì™€ í…Œì´ë¸” ì–´ëŠ ìª½ë„ ì•„ë‹ê²½ìš°)ì—는 lua_setmetatable() 함수는 0ì„ ë°˜í™˜í•œë‹¤. (당연한 얘기지만, ì´ë•Œì—는 ì•„ë¬´ê²ƒë„ popë˜ì§€ 않는다.)
12 루아 ì²í¬ë¥¼ 로딩하기 #
You can load a Lua chunk with
typedef const char * (*lua_Chunkreader) (lua_State *L, void *data, size_t *size); int lua_load (lua_State *L, lua_Chunkreader reader, void *data, const char *chunkname);
lua_load uses the reader to read the chunk. Everytime it needs another piece of the chunk, it calls the reader, passing along its data parameter. The reader must return a pointer to a block of memory with a new part of the chunk, and set size to the block size. To signal the end of the chunk, the reader must return NULL. The reader function may return pieces of any size greater than zero.
In the current implementation, the reader function cannot call any Lua function; to ensure that, it always receives NULL as the Lua state.
lua_load automatically detects whether the chunk is text or binary, and loads it accordingly (see program luac).
The return values of lua_load are:
- 0 - no errors;
- LUA_ERRSYNTAX - syntax error during pre-compilation.
- LUA_ERRMEM - memory allocation error.
See the auxiliar library (lauxlib) for examples of how to use lua_load, and for some ready-to-use functions to load chunks from files and from strings.
13 í…Œì´ë¸” 관리 #
í…Œì´ë¸”ì€ ë‹¤ìŒ í•¨ìˆ˜ë¥¼ 사용하여 ìƒì„±í• 수 있다.
void lua_newtable (lua_State *L);
ì´ í•¨ìˆ˜ëŠ” 새로운 텅빈 í…Œì´ë¸”ì„ ìƒì„±í•˜ê³ ê·¸ê²ƒì„ ìŠ¤íƒì— push한다.
스íƒì–´ë”˜ê°€ì— 위치한 í…Œì´ë¸”로부터 ê°’ì„ ì½ê¸° 위해서는 ë‹¤ìŒ í•¨ìˆ˜ë¥¼ 호출하ë¼. index는 í…Œì´ë¸”ì´ ìœ„ì¹˜í•œ ì¸ë±ìŠ¤ë¥¼ ì˜ë¯¸í•œë‹¤.
void lua_gettable (lua_State *L, int index);
ì´ í•¨ìˆ˜ëŠ” 스íƒìœ¼ë¡œë¶€í„° key를 pop 처리 한후, ê·¸ keyì— í•´ë‹¹í•˜ëŠ” í…Œì´ë¸”ì˜ ë‚´ìš©ë“¤ì„ ë‹¤ì‹œ 스íƒì— push한다. í…Œì´ë¸”ì€ ìŠ¤íƒìƒì— ìžˆì—ˆë˜ ìœ„ì¹˜ì— ê·¸ëŒ€ë¡œ 남겨진다. ì´ëŸ° ì ì€ í…Œì´ë¸”로부터 ì—¬ëŸ¬ê°œì˜ ê°’ì„ ì–»ëŠ”ë° ìœ ìš©í•˜ê²Œ 사용ë 수 있다.
루아ìƒì—서 í…Œì´ë¸”ì„ ì–µì„¸ìŠ¤í• ë•Œì™€ ê°™ì´, ì´ í•¨ìˆ˜ëŠ” "gettable"ì´ë‚˜ "index" ì´ë²¤íŠ¸ì— í•´ë‹¹í•˜ëŠ” 메타메소드를 기ë™í• ìˆ˜ë„ ìžˆë‹¤. ì–´ë–¤ ë©”íƒ€ë©”ì†Œë“œë„ ì‹¤í–‰í•˜ì§€ 않으면서 íŠ¹ì • í…Œì´ë¸” keyì— í•´ë‹¹í•˜ëŠ” ì‹¤ì œ ê°’ì„ ì–»ê¸° 위해서는 ë‹¤ìŒ í•¨ìˆ˜ë¥¼ 사용한다.
void lua_rawget (lua_State *L, int index);
ìŠ¤íƒ ì–´ë”˜ê°€ì— ìœ„ì¹˜í•œ í…Œì´ë¸”로 ê°’ì„ ì €ìž¥í•˜ë ¤ë©´, keyê°’ê³¼ ê·¸ì— ë”°ë¥¸ ê°’ì„ ìŠ¤íƒì— 순서대로 push í•˜ê³ ë‹¤ìŒ í•¨ìˆ˜ë¥¼ 호출하면 ëœë‹¤. (index는 í…Œì´ë¸”ì´ ìœ„ì¹˜í•œ 스íƒìƒì˜ ì¸ë±ìФì´ë‹¤.)
void lua_settable (lua_State *L, int index);
ì´ í•¨ìˆ˜ëŠ” ì‹¤í–‰í›„ì— pushí–ˆë˜ key와 ê·¸ì— ë”°ë¥¸ ê°’ì„ pop 처리한다. í…Œì´ë¸”ì€ ì›ëž˜ ìžˆë˜ ìžë¦¬ì— 남겨진다. ì´ í•¨ìˆ˜ë„ ì—시 "settable" ë˜ëŠ” "newindex" 메타메소드를 기ë™ì‹œí‚¬ 수 있다. ì´ ë©”íƒ€ë©”ì†Œë“œë¥¼ 기ë™í•˜ì§€ 않으면서 ê°’ì„ ì„¤ì •í•˜ë ¤ë©´ ë‹¤ìŒ í•¨ìˆ˜ë¥¼ 실행하면 ëœë‹¤.
void lua_rawset (lua_State *L, int index);
í…Œì´ë¸”ì˜ ë‚´ìš©ì„ í›‘ìœ¼ë ¤ë©´ ë‹¤ìŒ í•¨ìˆ˜ë¥¼ 사용한다. index는 í…Œì´ë¸”ì´ ìœ„ì¹˜í•œ 스íƒìƒì˜ ì¸ë±ìФì´ë‹¤.
int lua_next (lua_State *L, int index);
ì´ í•¨ìˆ˜ëŠ” 스íƒìœ¼ë¡œë¶€í„° keyê°’ì„ pop한 후, popì²˜ë¦¬ëœ Keyê°’ì˜ ë‹¤ìŒ ê°’ì— í•´ë‹¹ë˜ëŠ” keyê°’ê³¼ ê·¸ì— ëŒ€ì‘ë˜ëŠ” ì‹¤ì œê°’ì„ push한다. ë§Œì¼ ë”ì´ìƒ ë‹¤ìŒ ìš”ì†Œê°€ 없으면 0ì„ ë°˜í™˜í•œë‹¤. (ì´ë•ŒëŠ” ì•„ë¬´ê²ƒë„ pushë˜ì§€ 않는다.) 가장 처ìŒë¶€í„° 훑기 위해서는 nilì„ push한 후 ì´ í•¨ìˆ˜ë¥¼ 사용하ë¼.
ì „í˜•ì ì¸ í…Œì´ë¸”ì˜ í›‘ê¸° ìž‘ì—…ì€ ë‹¤ìŒê³¼ 같다.
/* 스íƒë‚´ì—서 í…Œì´ë¸”ì€ ì¸ë±ìФ tì— ìœ„ì¹˜í•´ìžˆë‹¤. */
lua_pushnil(L); /* 첫번째 Key를 훑ë„ë¡ ì„¤ì • */
while (lua_next(L, t) != 0)
{
/* keyê°’ì€ ì¸ë±ìФ -2ì— ìžˆê³ ëŒ€ì‘ë˜ëŠ” ê°’ì€ ì¸ë±ìФ -1ì— ìžˆë‹¤. */
printf("%s - %s\n", lua_typename(L, lua_type(L, -2)), lua_typename(L, lua_type(L, -1)));
lua_pop(L, 1); /* í‚¤ì— í•´ë‹¹ë˜ëŠ” ê°’ë§Œ ì œê±°í•œë‹¤. ë‹¤ìŒ í›‘ëŠ” 단계를 실행하기 위해 현재 keyê°’ì€ ë‚¨ê²¨ë‘”ë‹¤. */
}
ì£¼ì˜ : í…Œì´ë¸”ì„ í›‘ëŠ” 작업중ì—는 keyê°’ì— ì‹¤ì œ keyê°’ì´ ë¬¸ìžì—´ì¸ì§€ 확실하지 않으면 lua_tostring() 함수를 실행하지 ë§ì•„ë¼. lua_tostring()ì€ ì£¼ì–´ì§„ ì¸ë±ìŠ¤ì˜ ê°’ì„ ë¬¸ìžì—´ë¡œ 변환시킨다. 즉, ì´ëŸ° 경우ì—는 ì›ëž˜ í‚¤ê°’ì´ ë¬¸ìžì—´ì´ 아니ë¼ë©´ ë‹¤ìŒ lua_next() í˜¸ì¶œì‹œì— í˜¼ëž€ì„ ê°€ì ¸ì˜¬ 수 있다.
14 ì „ì— ë³€ìˆ˜ í…Œì´ë¸”ì„ ê´€ë¦¬í•˜ê¸° #
ëª¨ë“ ì „ì—변수는 ìƒì£¼í•˜ê³ 있는 루아 í…Œì´ë¸”ì•ˆì— ìœ ì§€ëœë‹¤. ì´ í…Œì´ë¸”ì€ ì–¸ì œë‚˜ 가짜 ì¸ë±ìФ LUA_GLOBALSINDEXì— ìœ„ì¹˜í•œë‹¤.
ì „ì— ë³€ìˆ˜ì˜ ê°’ì„ ì–µì„¸ìŠ¤í•˜ê±°ë‚˜ 변경하기 위해서 ì „ì—변수 í…Œì´ë¸”ì— í†µìƒì ì¸ í…Œì´ë¸” ëª…ë ¹ì„ ì‚¬ìš©í• ìˆ˜ 있다. 예를 들면 ì „ì—ë³€ìˆ˜ì˜ ê°’ì„ ì–µì„¸ìŠ¤í•˜ê¸°ìœ„í•˜ì—¬ 다ìŒê³¼ ê°™ì´ ì‹¤í–‰í•˜ë¼.
lua_pushstring(L, varname); lua_gettable(L, LUA_GLOBALSINDEX);
루아 ì“°ë ˆë“œì˜ ì „ì— í…Œì´ë¸”ì€ lua_replace() 함수를 사용하여 변경하는 ê²ƒì´ ê°€ëŠ¥í•˜ë‹¤.
15 í…Œì´ë¸”ì€ ë°°ì—´ë¡œì¨ ì‚¬ìš©í•˜ê¸° #
API는 ë‹¤ìŒ í•¨ìˆ˜ë“¤ì„ ì œê³µí•˜ì—¬ 루아 í…Œì´ë¸”ì„ ë°°ì—´ë¡œ 사용하는 ê²ƒì„ ë•는다. ì´ë•Œì—는 í…Œì´ë¸”ì€ ë‹¨ì§€ 숫ìžë¡œë§Œ ì¸ë±ìФë˜ì–´ìžˆì–´ì•¼ 한다.
void lua_rawgeti (lua_State *L, int index, int n); void lua_rawseti (lua_State *L, int index, int n);
lua_rawgeti()는 index ì¸ë±ìŠ¤ì— ìœ„ì¹˜í•œ í…Œì´ë¸”ì˜ n번째 ìš”ì†Œì˜ ê°’ì„ push한다. lua_rawseti()는 index ì¸ë±ìŠ¤ì— ìœ„ì¹˜í•œ í…Œì´ë¸”ì˜ n번째 ìš”ì†Œì˜ ê°’ì„ ìŠ¤íƒì˜ topì— ìœ„ì¹˜í•œ 값으로 ë®ì–´ì“°ê³ , pop처리한다. (즉, ì„¤ì •í• ê°’ì„ push 한 후 ì´ í•¨ìˆ˜ë¥¼ 실행하면 ëœë‹¤. ì‹¤í–‰í›„ì— push한 ê°’ì€ ì—†ì–´ì§„ë‹¤.)
16 Cì—서 루아 함수를 호출하기 #
루아내ì—서 ì •ì˜ëœ 함수와 ë£¨ì•„ë‚´ì— ë“±ë¡ëœ C í•¨ìˆ˜ë“¤ì€ í˜¸ìŠ¤íŠ¸ 프로그램ì—서 í˜¸ì¶œì´ ê°€ëŠ¥í•˜ë‹¤. ì´ê²ƒì€ 다ìŒê³¼ ê°™ì€ ê·œì¹™ì„ ì‚¬ìš©í•˜ì—¬ 실행ëœë‹¤.
- 호출ë 함수를 스íƒì— push한다.
- í•¨ìˆ˜ì˜ ì¸ìžë¡œ ì“°ì¼ ê°’ë“¤ì„ ì •ì˜ëœ ì¸ìž 순서대로 push한다. 다시ë§í•˜ë©´, 첫번째 ì •ì˜ëœ ì¸ìžëŠ” ë§¨ì²˜ìŒ push 한다.
- 마지막으로 lua_call()ì„ ì‹¤í–‰í•œë‹¤. nargs는 ì‹¤í–‰í• í•¨ìˆ˜ì˜ ì¸ìž 개수를 ì˜ë¯¸í•œë‹¤. nresults는 함수가 ì‹¤í–‰ëœ í›„ì˜ ë°˜í™˜ê°’ì˜ ê°œìˆ˜ë¥¼ ì˜ë¯¸í•œë‹¤. (LUA_MULTRET로 ì§€ì •í• ê²½ìš°ëŠ” 예외. ì´ ê²½ìš°ì—는, ëª¨ë“ ë°˜í™˜ê°’ì´ pushëœë‹¤. 루아는 ë°˜í™˜ê°’ë“¤ë•Œë¬¸ì— ìŠ¤íƒ ì˜¤ë²„í”Œë¡œìš°ê°€ ì¼ì–´ë‚˜ëŠ”ì§€ 살펴보게 ëœë‹¤.) í•¨ìˆ˜ì˜ ì‹¤í–‰ê²°ê³¼ê°’ì€ ìŠ¤íƒì— 순서대로 pushëœë‹¤. (첫번째 ê²°ê³¼ê°’ì´ ë§¨ì²˜ìŒ pushëœë‹¤.) 그러므로 호출 결과값중 가장 마지막 ê²°ê³¼ê°’ì´ topì— ìœ„ì¹˜í•˜ê²Œ ëœë‹¤. lua_call()ì˜ í•¨ìˆ˜ì •ì˜ëŠ” 다ìŒê³¼ 같다.
void lua_call(lua_State *L, int nargs, int nresults);
a = f("how", t.x, 14)
Cì—서는,
lua_pushstring(L, "t"); lua_gettable(L, LUA_GLOBALSINDEX); /* ì „ì— 't' (ë‚˜ì¤‘ì— ì‚¬ìš©) */ lua_pushstring(L, "a"); /* 변수명 */ lua_pushstring(L, "f"); /* 함수명 */ lua_gettable(L, LUA_GLOBALSINDEX); /* 호출ë 함수를 찾았다 */ lua_pushstring(L, "how"); /* 첫번째 ì¸ìžê°’ */ lua_pushstring(L, "x"); /* "x"ë¼ëŠ” ì´ë¦„ì˜ ë³€ìˆ˜ê°’ì„ tí…Œì´ë¸”ì—서 ì°¾ì„ ê²ƒì´ë‹¤ */ lua_gettable(L, -5); /* t.xì˜ ê°’ì„ push한다. (ë‘번째 ì¸ìž) */ lua_pushnumber(L, 14); /* 세번째 ì¸ìžê°’ */ lua_call(L, 3, 1); /* ìž, 3ê°œì˜ ì¸ìžì™€ 1ê°œì˜ ë°˜í™˜ê°’ì„로 실행ë˜ë„ë¡ í•¨ìˆ˜ 실행! */ lua_settable(L, LUA_GLOBALSINDEX); /* ì „ì— í…Œì´ë¸”ìƒì—서 "a"ì—다가 ê²°ê³¼ê°’ì„ ì„¤ì •í•œë‹¤. */ lua_pop(L, 1); /* 스íƒìœ¼ë¡œ 부터 "t"를 ì œê±°í•œë‹¤. */
위 코드가 "ê· í˜•ì 으로" 실행ëœë‹¤ëŠ” ì ì— ì£¼ëª©í•˜ë¼. ì½”ë“œì˜ ë§ˆì§€ë§‰ì—는 스íƒì´ ì›ëž˜ì˜ ìƒíƒœë¡œ ëŒì•„가는 ê²ƒì„ ì•Œ 수 있다. ì´ê²ƒì€ ì¢‹ì€ í”„ë¡œê·¸ëž˜ë° ì—°ìŠµì´ ë 수 있다.
(단지 루아 APIì— ì˜í•´ ì œê³µë˜ëŠ” 함수들로만 ì´ ì˜ˆì œë¥¼ 구현했다. ì¼ë°˜ì 으로 í”„ë¡œê·¸ëž˜ë¨¸ë“¤ì€ ë£¨ì•„ì˜ ìƒìœ„ë ˆë²¨ 억세스를 ì œê³µí•˜ëŠ” 몇가지 매í¬ë¡œë“¤ê³¼ ë³´ì¡° í•¨ìˆ˜ë“¤ì„ ì‚¬ìš©í•œë‹¤. 사용한 예를 ë‹¤ìŒ ì´ì–´ì§€ëŠ” ì˜ˆì œë¥¼ 참조하ë¼.)
ë§Œì¼ ë‹¤ìŒê³¼ ê°™ì€ ë£¨ì•„ 함수가 ì„ ì–¸ë˜ì–´ìžˆë‹¤ê³ ê°€ì •í•œë‹¤ë©´,
function calcexam(x, y) return (x^2 + y) end
ì´ë¥¼ 호출하는 C 소스는 다ìŒê³¼ ê°™ì´ ì ì„ ìˆ˜ 있다.
lua_getglobal(L, "calcexam"); // calcexam 함수를 사용하는 것으로 ì„¤ì •
if (lua_isfunction(L, 1)) // 혹시나 함수타입ì¸ì§€ 검사해본다.
{
lua_pushnumber(L, 10); // 첫번째 ì¸ìžëŠ” 10으로 ì„¤ì •
lua_pushnumber(L, 2); // ë‘번째 ì¸ìžëŠ” 2로 ì„¤ì •
lua_call(L, 2, 1); // 함수 실행!
int result = (int)lua_tonumber(L, -1); // ê²°ê³¼ê°’ì„ resultì— ë‹´ëŠ”ë‹¤. ì•„ë§ˆë„ 102ê°€ 담길 것ì´ë‹¤.
lua_pop(L, 1); // ë§¨ì²˜ìŒ ì¶”ê°€í–ˆë˜ í•¨ìˆ˜ë¥¼ 스íƒì—서 pop 처리한다.
}
17 Protected Calls #
When you call a function with lua_call, any error inside the called function is propagated upwards (with a longjmp). If you need to handle errors, then you should use lua_pcall:
int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);
Both nargs and nresults have the same meaning as in lua_call. If there are no errors during the call, lua_pcall behaves exactly like lua_call. Like lua_call, lua_pcall always removes the function and its arguments from the stack. However, if there is any error, lua_pcall catches it, pushes a single value at the stack (the error message), and returns an error code.
If errfunc is 0, then the error message returned is exactly the original error message. Otherwise, errfunc gives the stack index for an error handler function. (In the current implementation, that index cannot be a pseudo-index.) In case of runtime errors, that function will be called with the error message, and its return value will be the message returned by lua_pcall.
Typically, the error handler function is used to add more debug information to the error message, such as a stack traceback. Such information cannot be gathered after the return of lua_pcall, since by then the stack has unwound.
The lua_pcall function returns 0 in case of success, or one of the following error codes (defined in lua.h):
- LUA_ERRRUN - a runtime error.
- LUA_ERRMEM - memory allocation error. For such errors, Lua does not call the error handler function.
- LUA_ERRERR - error while running the error handler function.
void lua_error (lua_State *L, const char *message);
This function never returns. If lua_error is called from a C function that has been called from Lua, then the corresponding Lua execution terminates, as if an error had occurred inside Lua code. Otherwise, the whole host program terminates with a call to exit(EXIT_FAILURE). Before terminating execution, the message is passed to the error handler function, _ERRORMESSAGE (see Section 3.6). If message is NULL, then _ERRORMESSAGE is not called.
The function
void lua_concat (lua_State *L, int n);
concatenates the n values at the top of the stack, pops them, and leaves the result at the top. If n is 1, the result is that single string (that is, the function does nothing); if n is 0, the result is the empty string. Concatenation is done following the usual semantics of Lua (see Section 3.4.4).
18 C 함수를 ë£¨ì•„ì— ë“±ë¡í•˜ê¸° #
루아는 C언어로 ìž‘ì„±ëœ í•¨ìˆ˜ë“¤ë¡œ 확장ë 수 있다. ì´ í•¨ìˆ˜ë“¤ì€ ë°˜ë“œì‹œ 아래와 ê°™ì´ ì •ì˜ëœ lua_CFunction 타입으로 ì •ì˜ë˜ì–´ì•¼ 한다.
typedef int (*lua_CFunction) (lua_State *L);
루아 ë‚´ì— ì‚¬ìš©ë C 함수는 ì–¸ì œë‚˜ 루아 í™˜ê²½ì„ ì˜ë¯¸í•˜ëŠ” state 변수를 ì¸ìžë¡œ ë°›ê³ , ë°˜í™˜ê°’ì˜ ê°œìˆ˜ë¥¼ ì˜ë¯¸í•˜ëŠ” integer ê°’ì„ ë°˜í™˜í•˜ëŠ” 구조를 가진다.
루아와 ì•Œë§žì€ í†µì‹ ì„ í•˜ê¸° 위해서는 C 함수는 다ìŒê³¼ ê°™ì€ í”„ë¡œí† ì½œì„ ë”°ë¥¸ë‹¤ : C 함수는 스íƒì„ 사용하여 루아로부터 í•¨ìˆ˜ì˜ ì¸ìžë“¤ì„ 넘겨받는다. ê·¸ 순서는 순방향(가장 ì²˜ìŒ ì¸ìžê°€ 가장 ë¨¼ì € 푸쉬ëœë‹¤.)으로 ì§€ì •ëœë‹¤. 루아로 ê°’ì„ ë°˜í™˜í•˜ê¸° 위해서는 C 함수는 스íƒìœ¼ë¡œ ê·¸ ë°˜í™˜ê°’ë“¤ì„ í‘¸ì‰¬í•œë‹¤. ì´ ìˆœì„œë„ ì—시 순방향ì´ë‹¤. (가장 첫번째 ë°˜í™˜ê°’ì´ ê°€ìž¥ ë¨¼ì € 푸쉬ëœë‹¤.) 루아ì—서 ì„ ì–¸ëœ í•¨ìˆ˜ì™€ ê°™ì´, 루아내ì—서 사용ë C í•¨ìˆ˜ë„ ì—¬ëŸ¬ê°œì˜ ê²°ê³¼ê°’ì„ ë°˜í™˜í• ìˆ˜ 있다.
예를 들어 ì—¬ëŸ¬ê°œì˜ ìˆ˜ì¹˜ë¥¼ 받아 í‰ê· ê³¼ 합계를 반환하는 ë‚´ìš©ì˜ ë‹¤ìŒê³¼ ê°™ì€ í•¨ìˆ˜ë¥¼ ì •ì˜í• 수 있다.
static int foo (lua_State *L) {
int n = lua_gettop(L); /* ì¸ìžì˜ 개수 */
lua_Number sum = 0;
int i;
for (i = 1; i <= n; i++)
{
if (!lua_isnumber(L, i))
{
lua_pushstring(L, "incorrect argument to function `average'");
lua_error(L);
}
sum += lua_tonumber(L, i);
}
lua_pushnumber(L, sum/n); /* 첫번째 반환값 */
lua_pushnumber(L, sum); /* ë‘번째 반환값 */
return 2; /* ë°˜í™˜ê°’ì˜ ê°œìˆ˜ë¥¼ 반환 */
}
루아로 C 함수를 등ë¡í•˜ê¸° 위한 다ìŒê³¼ ê°™ì€ íŽ¸ë¦¬í•œ 매í¬ë¡œê°€ 존재한다.
#define lua_register(L,n,f) \
(lua_pushstring(L, n), \
lua_pushcfunction(L, f), \
lua_settable(L, LUA_GLOBALSINDEX))
/* const char *n; */
/* lua_CFunction f; */
ì´ ë§¤í¬ë¡œëŠ” 루아 환경 state 변수, 루아내ì—서 ì‚¬ìš©í• ì´ë¦„, ê·¸ë¦¬ê³ í•¨ìˆ˜ì˜ í¬ì¸í„°ë¥¼ ì¸ìžë¡œ 받는다. ë”°ë¼ì„œ ë‹¤ìŒ ì˜ˆëŠ” C 함수 'foo'를 'average'ë¼ëŠ” ì´ë¦„ì˜ ë£¨ì•„ 함수로 등ë¡í•œë‹¤.
lua_register(L, "average", foo);
19 Defining C Closures #
When a C function is created, it is possible to associate some values to it, thus creating a C closure; these values are then accessible to the function whenever it is called. To associate values to a C function, first these values should be pushed onto the stack (when there are multiple values, the first value is pushed first). Then the function
void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
is used to push the C function onto the stack, with the argument n telling how many values should be associated with the function (lua_pushcclosure also pops these values from the stack); in fact, the macro lua_pushcfunction is defined as lua_pushcclosure with n set to 0.
Then, whenever the C function is called, those values are located at specific pseudo-indices. Those pseudo-indices are produced by a macro lua_upvalueindex. The first value associated with a function is at position lua_upvalueindex(1), and so on.
For examples of C functions and closures, see files lbaselib.c, liolib.c, lmathlib.c, and lstrlib.c in the official Lua distribution.
19.1 Registry #
Lua provides a pre-defined table that can be used by any C code to store whatever Lua value it needs to store, especially if the C code needs to keep that Lua value outside the life span of a C function. This table is always located at pseudo-index LUA_REGISTRYINDEX. Any C library can store data into this table, as long as it chooses keys different from other libraries. Typically, you should use as key a string containing your library name, or a light userdata with the address of a C object in your code.
The integer keys in the registry are used by the reference mechanism, implemented by the auxiliar library, and therefore should not be used by other purposes.
Cì—서 루아 함수 호출 코드ì—서 오류를 발견했습니다.
lua_getglobal(L, "calcexam"); // calcexam 함수를 사용하는 것으로 ì„¤ì •
if (lua_isfunction(L, 1)) // 혹시나 함수타입ì¸ì§€ 검사해본다.
{
lua_pushnumber(L, 10); // 첫번째 ì¸ìžëŠ” 10으로 ì„¤ì •
lua_pushnumber(L, 2); // ë‘번째 ì¸ìžëŠ” 2로 ì„¤ì •
lua_call(L, 2, 1); // 함수 실행!
int result = (int)lua_tonumber(L, -1); // ê²°ê³¼ê°’ì„ resultì— ë‹´ëŠ”ë‹¤. ì•„ë§ˆë„ 102ê°€ 담길 것ì´ë‹¤.
lua_pop(L, 1); // ë§¨ì²˜ìŒ ì¶”ê°€í–ˆë˜ í•¨ìˆ˜ë¥¼ 스íƒì—서 pop 처리한다.
}
여기서 lua_isfunction(L, 1)ì€ ë§ˆì§€ë§‰ì— push한 "calcexam"ì˜ íƒ€ìž…ì„ ì²´í¬í•˜ëŠ” 것ì´ë‹ˆ lua_isfunction(L, -1)ì´ ë˜ì–´ì•¼ 합니다.
lua_isfunction(L, 1)로 하니까 함수가 아니ë¼ê³ 나오ë”êµ°ìš”.
ê·¸ë¦¬ê³ ë§ˆì§€ë§‰ì˜ // ë§¨ì²˜ìŒ ì¶”ê°€í–ˆë˜ í•¨ìˆ˜ë¥¼ 스íƒì—서 pop 처리한다.ë¼ëŠ” 주ì„ì€ í•¨ìˆ˜ë¥¼ pop하는 ê²ƒì´ ì•„ë‹ˆë¼ ë¦¬í„´ê°’ì„ popì²˜ë¦¬í•œë‹¤ê³ í•´ì•¼ê² ì£ . -- 211.196.83.47 2004-12-01
현재 메뉴얼 소스ìžì²´ì— 버그가 있는 모양입니다. 퀵 ë ˆí¼ëŸ°ìФ 형태로 ì œ ë‚˜ë¦„ëŒ€ë¡œì˜ ë©”ë‰´ì–¼ì„ ì •ë¦¬ì¤‘ìž…ë‹ˆë‹¤. 그걸 ìœ„í‚¤ì— ì˜¬ë¦¬ë©´ ì´ ê¸€ì€ ì§€ìš¸ ì˜ˆì •ìž…ë‹ˆë‹¤. -- redpixel 2004-12-01








