
C005_ARM 보드에서 루아 이용 - 루아 스크립트에서 정의된 함수 호출 1
1. 개요
이 문서는 ARM 보드에서 동작하는 C 프로그램이 루아 스크립트에 정의된 함수를
호출하는 방법을 기술 합니다.
이 문서에서는 다음과 같은 내용을 다룹니다.
* 루아 스크립트 라이브러리를 포함하는 C 컴파일 용 Makefile
* 루아 스크립트를 호출하고 값을 얻어 오는 C 샘플 main.c
* 호출 되는 루아 스크립트 run.lua
2. 실습 구성
다음과 같은 디렉토리 구성을 하였습니다.
/project/lua/sample_lua_arm/lua_include : LUA 헤더 파일 모음
/project/lua/sample_lua_arm/lua_lib : LUA 라이브러리 소스 모음
/project/lua/sample_lua_arm/lua_samples : 앞으로 진행할 강좌의 소스 들
3. 기본 샘플 구성
소스는 다음 디렉토리에 위치 합니다.
/project/lua/sample_lua_arm/lua_samples/050_call_function_from_script
이 디렉토리에는 다음과 같은 파일이 있습니다.
Makefile
main.c
run.lua
4. 소스들
Makefile --------------------------------------------------------------------------------
CROSS_PREFIX = arm-linux TARGET = app_run_lua TARGET_NFS = /nfs/lua
C_SRCS = C_SRCS += main.c
LUA_SRCS = run.lua
# LUA Support -- CORE C_SRCS += ../../lua_lib/lapi.c C_SRCS += ../../lua_lib/lcode.c C_SRCS += ../../lua_lib/ldebug.c C_SRCS += ../../lua_lib/ldo.c C_SRCS += ../../lua_lib/ldump.c C_SRCS += ../../lua_lib/lfunc.c C_SRCS += ../../lua_lib/lgc.c C_SRCS += ../../lua_lib/llex.c C_SRCS += ../../lua_lib/lmem.c C_SRCS += ../../lua_lib/lobject.c C_SRCS += ../../lua_lib/lopcodes.c C_SRCS += ../../lua_lib/lparser.c C_SRCS += ../../lua_lib/lstate.c C_SRCS += ../../lua_lib/lstring.c C_SRCS += ../../lua_lib/ltable.c C_SRCS += ../../lua_lib/ltm.c C_SRCS += ../../lua_lib/lundump.c C_SRCS += ../../lua_lib/lvm.c C_SRCS += ../../lua_lib/lzio.c
# LUA Support -- LIB C_SRCS += ../../lua_lib/lauxlib.c C_SRCS += ../../lua_lib/lbaselib.c C_SRCS += ../../lua_lib/ldblib.c C_SRCS += ../../lua_lib/liolib.c C_SRCS += ../../lua_lib/lmathlib.c C_SRCS += ../../lua_lib/loslib.c C_SRCS += ../../lua_lib/ltablib.c C_SRCS += ../../lua_lib/lstrlib.c C_SRCS += ../../lua_lib/loadlib.c C_SRCS += ../../lua_lib/linit.c
INCLUDES += -I. INCLUDES += -I/usr/local/include INCLUDES += -I/usr/$(CROSS_PREFIX)/include INCLUDES += -I../../include
INCLUDES += -I../../lua_include
LDFLAGS += -L../../lua_lib/ LDFLAGS += -L/usr/$(CROSS_PREFIX)/lib
LIBS = -lm
CFLAGS += $(INCLUDES) CFLAGS += -Wall -O2 -g
ARFLAGS = rs
#--------------------------------------------------------------------- CC = $(CROSS_PREFIX)-gcc AR = $(CROSS_PREFIX)-ar rc AR2 = $(CROSS_PREFIX)-ranlib RANLIB = $(CROSS_PREFIX)-ranlib LD = $(CROSS_PREFIX)-ld NM = $(CROSS_PREFIX)-nm STRIP = $(CROSS_PREFIX)-strip OBJCOPY = $(CROSS_PREFIX)-objcopy CP = cp MV = mv #--------------------------------------------------------------------
C_OBJS = $(C_SRCS:%.c=%.o)
%.o:%.c @echo "Compiling $< ..." $(CC) -c $(CFLAGS) -o $@ $<
all : $(TARGET) $(LUA_SRCS) cp $(TARGET) $(TARGET_NFS) cp $(LUA_SRCS) $(TARGET_NFS)
$(TARGET) : $(C_OBJS) $(CC) $(LDFLAGS) $(C_OBJS) -o $@ $(LIBS)
dep : $(CC) -M $(INCLUDES) $(C_SRCS) > .depend
clean: rm -f *.bak rm -f *.map rm -f *.o rm -f $(C_OBJS) rm -f $(TARGET) core
distclean: clean rm -rf .depend
ifeq (.depend,$(wildcard .depend)) include .depend endif
run.lua --------------------------------------------------------------------------------
print( "ENTER RUN.LUA" )
function sample_function() print( ">>> Hello! I am lua function" ) end
print( "END........." )
main.c --------------------------------------------------------------------------------
#include <stdio.h> #include <string.h> #include <lua.h> #include <lauxlib.h> #include <lualib.h>
#define LUA_FILENAME "run.lua"
int main( int argc, char **argv ) { lua_State *L = NULL; int error; int int_value; char *str_value; int len_value; int stack_enter; int stack_table; printf( "sample : C function call Lua Script \n" ); L = luaL_newstate(); luaL_openlibs(L); error = luaL_loadfile( L, LUA_FILENAME ) || lua_pcall ( L, 0,0,0 ); printf( "Enter C routine\n" ); if( error ) { printf( "%s\n", lua_tostring(L,-1)); lua_pop(L,1); exit(0); } lua_getglobal( L,"sample_function" ); // <<-- (1) lua_pcall( L, 0,0,0 ); // <<-- (2) lua_close(L); printf( "sample end\n" ); return 0; }
5 소스 설명
(1) 함수를 스택으로 복사해 옵니다.
루아 스크립트에서 정의된 내용을 C에서 사용하려면 항상
스택으로 복사해 와야 한다는 것을 기억해야 합니다.
복사해 온다고 해서 함수 자체를 복사해 오는 것이 아니라
함수 객체만을 가져 오는 겁니다.
변수는 스택 위치를 지정하지만
함수는 호출하는 함수들이 스택 위치를 지정할수 없습니다.
그러므로 하나의 함수만이 호출 가능합니다.
(2) 스택에 옮겨진 함수를 호출합니다.
5.1 스택의 변화 설명
각 단계별 스택의 상황을 표시하면 다음과 같습니다.
(1) 단계를 거치면 다음과 같은 스택 상태가 됩니다. | | +------------------+ 1 | sample_function | -1 <-- stack_table = 1 +------------------+
(2) 단계를 거치면 다음과 같은 스택 상태가 됩니다. + + | | 0 +------------------+ 0
6. 결론
루아 스크립트에 선언된 함수를 호출할 때는
1) lua_getglobal() 함수를 이용하여 스택으로 값을 복사합니다.
2) lua_pcall() 함수를 이용하여 호출합니다.
7 수행 예
다음은 보드에서 수행한 예 입니다.
[root@falinux nfs]$ ./app_run_lua
sample : C function call Lua Script
ENTER RUN.LUA
END.........
Enter C routine
>>> Hello! I am lua function
sample end
[root@falinux nfs]$