
1. 개요
이 문서는 ARM 보드에서 동작하는 루아 스크립트에서 C 함수를 호출하는 방법을 기술 합니다.
루아 스크립트에서 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/080_lua_pcall_error
이 디렉토리에는 다음과 같은 파일이 있습니다.
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" ) print( "call c function from lua script" ) c_sample_function(); 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 c_sample_function( lua_State *L ) { printf( "Enter c_sample_function\n" ); printf( "Exit c_sample_function\n" ); return 0; } int main( int argc, char **argv ) { lua_State *L = NULL; int error; printf( "sample : call c function from lua\n" ); L = luaL_newstate(); luaL_openlibs(L); lua_pushcfunction(L,c_sample_function ); // <<-- (1) lua_setglobal(L, "c_sample_function" ); // <<-- (2) error = luaL_loadfile( L, LUA_FILENAME ) // <<-- (3) || 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_close(L); printf( "sample end\n" ); return 0; }
5 소스 설명
(1) 루아 스크립트에서 호출될 함수 c_sample_function()를 lua_pushcfunction()함수를 이용하여
스택에 밀어 넣습니다.
(2) 스택에 있는 함수를 루아 스크립트에서 호출할수 있도록 만듭니다.
(3) 루아 스크립트를 호출 합니다. 이후 루아 스크립트에서
c_sample_function() 를 호출하게 됩니다.
5.1 스택의 변화 설명
각 단계별 스택의 상황을 표시하면 다음과 같습니다.
(1) C 함수를 스택에 넣은 상태입니다.
| |
+--------------------+
1 | c_sample_function | -1
+--------------------+
(2) lua_setglobal() 함수를 호출하여 c_sample_function() 함수가 전역화 되면서 제거 됩니다.
| |
+--------------------+
6. 결론
루아 스크립트에서 C 함수를 호출하려면
1) 루아 스크립트를 로드하고 실행하기 전에
2) lua_pushcfunction()를 사용하여 스택에 넣은 후
3) lua_setglobal()를 사용하여 호출 가능하게 만들어야 합니다.
7 수행 예
다음은 보드에서 수행한 예 입니다.
[root@falinux nfs]$ ./app_run_lua
sample : call c function from lua
ENTER RUN.LUA
call c function from lua script
Enter c_sample_function
Exit c_sample_function
END.........
Enter C routine
sample end
[root@falinux nfs]$