사용자 도구

사이트 도구


kb:tolua

ToLua++

C/C++ 쪽에 있는 기능을 루아 쪽으로 노출시키기 위해 사용하는 솔루션. SWIG와 여러 모로 비슷한 넘이다.

동작 방식을 간단히 나열해 보자면 다음과 같다.

  1. 헤더 파일에 있는 내용 중에 익스포트할 내용들을 간추린 “패키지” 파일이라는 것을 만든다.
  2. 패키지 파일에 있는 내용을 기초로, 바인딩에 필요한 래퍼 헤더/소스를 만든다.
    tolua++ -n test -H test_package.h -o test_package.cpp test.pkg
  3. 생성된 래퍼 헤더/소스를 원래 애플리케이션과 함께 빌드한다.

패키지 파일 뽑아내는 부분과, 바인딩에 필요한 래퍼 헤더/소스 만드는 부분을 자동화해야 편하게 사용할 수 있을 것 같다.

예제

소스 준비

익스포트할 소스를 물색(?)한다.

test.h

#pragma once
 
class example
{
public:
    int m_value;
 
public:
    example() : m_value(0) {}
    example(int value) : m_value(value) {}
    ~example() {}
 
public:
    int get_value() { return m_value; }
    void set_value(int value) { m_value = value; }
};
 
int add(example& a, example& b);
int subtract(example& a, example& b);

test.cpp

#include "test.h"
 
int add(example& a, example& b)
{
    return a.get_value() + b.get_value();
}
 
int subtract(example& a, example& b)
{
    return a.get_value() - b.get_value();
}

패키지 파일 작성

헤더 파일에서 익스포트할 부분만 빼서, ” tolua_begin”, ” to_lua_end” 쌍으로 감싸준다. tolua 전처리 구문이 필요없다면 C/C++ 헤더를 바로 써도 된다.

test.pkg

// tolua_begin
class example
{
public:
    int m_value;

public:
    example() : m_value(0) {}
    example(int value) : m_value(value) {}
    ~example() {}

public:
    int get_value() { return m_value; }
    void set_value(int value) { m_value = value; }
};

int add(example& a, example& b);
int subtract(example& a, example& b);
// tolua_end

래퍼 헤더/소스 파일 생성

tolua++ -n test -H output.h -o output.cpp test.pkg

명령을 실행하면 아래와 같은 파일이 생성된다. 생성된 파일을 프로젝트에다 추가하고 같이 컴파일하면 된다.

output.h

/*
** Lua binding: test
** Generated automatically by tolua++-1.0.92 on 07/25/06 21:25:32.
*/
 
/* Exported function */
TOLUA_API int  tolua_test_open (lua_State* tolua_S);

output.cpp

/*
** Lua binding: test
** Generated automatically by tolua++-1.0.92 on 07/25/06 21:25:32.
*/
 
#ifndef __cplusplus
#include "stdlib.h"
#endif
#include "string.h"
 
#include "tolua++.h"
 
/* Exported function */
TOLUA_API int  tolua_test_open (lua_State* tolua_S);
 
#include "test.h"
 
/* function to release collected object via destructor */
#ifdef __cplusplus
 
static int tolua_collect_example (lua_State* tolua_S)
{
 example* self = (example*) tolua_tousertype(tolua_S,1,0);
    delete self;
    return 0;
}
#endif
 
... 생략 ...

익스포트된 기능 사용

프로젝트 설정에서 tolualib 라이브러리 파일을 링크해주고, 루아 상태 객체 초기화하는 부분에서 tolua 프로그램을 이용해 생성한 패키지 오픈 함수를 호출해줘야 한다.

void init_lua_state(lua_State* L)
{
    ...
    // 루아 상태 초기화 부분 어딘가...
    tolua_test_open(L);
    ...
}

이후부터는 그냥 사용하면 된다.

a = example:new(1000)
b = example:new(3000)
print(add(a, b))
print(subtract(a, b))
4000
-2000

링크

kb/tolua.txt · 마지막으로 수정됨: 2014/11/06 17:30 (바깥 편집)