Lua와 C 바인딩

2015. 9. 20. 23:39프로그래밍/Script

728x90
728x90

스택 이해하기

C와 lua간 연동에 중요한 요소는 가상 스택이다.

lua의 스택 액세스 방법은 절대/상대 접근이 있다.


양수 값 - 절대 접근

음수 값 - 상대 접근


절대 접근 방법은 스택 base에서 시작해 양수 1,2,3으로 순서를 부여하는 방법이다.

상대 접근 방법은 스택 top에서 시작해 음수 -1,-2,-3으로 순서를 부여하는 방법이다.


*스택의 마지막 값을 접근 시 -1, 바닥부터 접근 시 1




lua_checkstack : 스택 사이즈를 확인하기 위한 lua C API


LUA_MINSTACK 20 으로 정의


허용 가능한 스택 인덱스 범위는

1
(index < 0 && abs(index) <= top) || (index > 0 && index <= stackspace )
cs


글로벌 테이블의 의사인덱스 : LUA_GLOBALSINDEX


Lua에서 C 함수 호출

순서

C함수 정의 - C함수 lua에 등록 - lua에서 등록된 함수 호출


우선 Visual Sutdio랑 연동(VS2012)

https://code.google.com/p/luaforwindows/downloads/detail?name=LuaForWindows_v5.1.4-46.exe&can=2&q=

에서 luaforwindows 설치

cmd에서 lua를 이용할 수 있다.


버전에 맞는 루아 바이너리 받기

난 VS2012용 정적 라이브러리를 받았다.


디렉토리 지정과 추가종속성 지정에 대한 설명은 생략한다.


예제

main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
extern "C"
{
    #include "lua.hpp"
}
 
// 함수 정의
int luaHello(lua_State* L) 
{
    int count = 0;
    // luaL_checkstring을 통해 루아에서 넘어온 값을 가져온다.
    // 양수 1은 stack base의 첫 번째 값으로 루아에서 넘어온 첫 인자.
    const char* name = luaL_checkstring(L, 1);
    count++;
    printf("%s\n", name);
 
    // test 
    name = luaL_checkstring(L, 2);
    count++;
    printf("%s\n", name);
    return count;
}
 
// 메인
void main()
{
    lua_State *lua = luaL_newstate();
    luaL_openlibs(lua);
    // 함수 등록하기
    lua_register(lua, "hello", luaHello);
    // hello.lua에서 읽기
    luaL_dofile(lua, "hello.lua");
    // 루아 닫기
    lua_close(lua);
}
cs


hello.lua

1
2
hello("alice""vorpal sword")
hello("hello""kowabunga!")
cs




이게 말이 좀 애매해서 한참을 봤다.

C에서 정의한 함수를 루아 스크립트만 돌렸을 때는 당연히 안되고

컴파일 했을 때 루아에 있는 스크립트에서 C 함수가 작동된다는 말... 참 한글 어렵죠.


C에서 lua 함수 호출하기

lua 함수를 스택에 올림 - 스택에 있는 함수를 실행


lua 함수 스택에 올리기

1
2
3
4
5
6
7
8
9
//case1)
lua_pushstring("function");
lua_gettable(lua, LUA_GLOBALSINDEX);
 
//case2)
lua_getfield(lua, LUA_GLOBALSINDEX, "function");
 
//case3)
lua_getglobal(lua, "function");
cs


세 가지중 하나로. LUA_GLOBASINDEX를 5.2버전에서는 사용할 수 없다고 한다.


main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <string>
extern "C"
{
#include "lua.hpp"
}
 
// 함수 정의
int luaHello(lua_State* L) 
{
    int count = 0;
    // luaL_checkstring을 통해 루아에서 넘어온 값을 가져온다.
    // 양수 1은 stack base의 첫 번째 값으로 루아에서 넘어온 첫 인자.
    const char* name = luaL_checkstring(L, 1);
    count++;
    printf("%s\n", name);
 
    // test 
    name = luaL_checkstring(L, 2);
    count++;
    printf("%s\n", name);
    return count;
}
 
// 메인
void main()
{
    // 초기화
    lua_State *lua = luaL_newstate();
    luaL_openlibs(lua);
    
    // 루아에서 C함수 사용하기
    // 함수 등록하기
    lua_register(lua, "hello", luaHello);
    // hello.lua에서 읽기
    luaL_dofile(lua, "hello.lua");
 
    lua_getglobal(lua, "popura");
    if (lua_isfunction(lua, -1== false
    {
        fprintf(stderr, "print is not function\n");
        return;
    }
 
    // C에서 루아 함수 사용하기
    // 스택 탑 구하기
    int top = lua_gettop(lua);
    lua_getglobal(lua, "popura");
    if (lua_isfunction(lua, -1== false
    {
        return;
    }
 
    // pcall 에러 핸들러
    int handle = lua_pcall(lua, 0, LUA_MULTRET, 0);
 
    if (handle) 
    {
        fprintf(stderr, "call error: %s\n", lua_tostring(lua, -1));
        return;
    }
 
    int ret_cnt = lua_gettop(lua) - top;
    printf("ret_cnt = %d\n", ret_cnt);
 
    int ret_val1 = 0;
    std::string ret_val2;
 
    // 스택 탑에서 문자값 가져오기
    ret_val2 = luaL_checkstring(lua, -1);
    // 스택 팝
    lua_pop(lua, 1);
    // 스택 탑에서 숫자값 가져오기
    ret_val1 = static_cast<int>(luaL_checknumber(lua, -1));
    // 스택 팝
    lua_pop(lua, 1);
    
    // 루아에서 가져온 값 출력
    printf("%d, %s", ret_val1, ret_val2.c_str());
 
    // 루아 닫기
    lua_close(lua);
}
cs


hello.lua

1
2
3
4
5
6
function popura()
    return 1"popura"
end
 
hello("alice""vorpal sword")
hello("hello""kowabung")
cs


결과


728x90
반응형

'프로그래밍 > Script' 카테고리의 다른 글

[Lua, Json] lua에서 json 처리하기. json for lua  (3) 2016.01.15
[루아] Lua에서 .과 :의 차이(?) + OOP  (4) 2015.12.17
개론  (2) 2015.10.01
Lua 메타테이블  (0) 2015.09.20
Lua 5.x와 4.0 호환성  (0) 2015.09.20
Lua 조건문, 반복문  (0) 2015.09.19
Lua 연산자  (0) 2015.09.19