
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
endifrun.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]$


