본문 바로가기
Lua

lua 설치 및 hello world 찍기

by SpeeDr00t 2017. 9. 12.
반응형

lua 설치 및 hello world 찍기

c언어에서 lua호출 하기

c++에서 lua호출하기


1. 환경설정


■ lua 설치

sudo apt-get install lua5.2
버전 확인
lua -v
luac -v
sudo apt-get install liblua5.2-dev
ls -ltr /usr/include/lua5.2/



 

 

2. hello world 찍기

■ 0x01.helloworld.lua 파일명으로 저장

print("hello world!!!");

 

■ 0x01.helloworld.lua 컴파일 하기

lua 0x01.helloworld.lua


 

 

 

3. c언어에서 lua 호출하기

■ hello.c 파일명으로 저장

#include "lua.h"
#include "lauxlib.h"
int main(int argc, char **argv)
{
    lua_State *L = luaL_newstate();
    luaL_openlibs(L);
    luaL_dostring(L, "print('hello, '.._VERSION)");
    return 0;

}

 

 

■ hello.c 컴파일 및 실행

gcc -I/usr/include/lua5.2 -o hello hello.c -llua5.2 -lm
./hello

 

 

 

4. c++에서 lua 호출하기

 

■ 0x01.bind.cpp 파일명으로 저장

extern "C"
{
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
 
#include <iostream>
#include <sstream>
 
class Foo
{
public:
    Foo(const std::string & name) : name(name)    {
        std::cout << "Foo is born" << std::endl;
    }       std::string Add(int a, int b)    {         std::stringstream ss;         ss << name << ": " << a << " + " << b << " = " << (a+b);         return ss.str();    }     ~Foo()     {        std::cout << "Foo is gone" << std::endl;    }   private:     std::string name; };   // The general pattern to binding C++ class to Lua is to write a Lua // thunk for every method for the class, so here we go:   int l_Foo_constructor(lua_State * l) {     const char * name = luaL_checkstring(l, 1);       // We could actually allocate Foo itself as a user data but     // since user data can be GC'ed and we gain unity by using CRT's heap     // all along.     Foo ** udata = (Foo **)lua_newuserdata(l, sizeof(Foo *));     *udata = new Foo(name);       // Usually, we'll just use "Foo" as the second parameter, but I     // say luaL_Foo here to distinguish the difference:     //     // This 2nd parameter here is an _internal label_ for luaL, it is     // _not_ exposed to Lua by default.     //     // Effectively, this metatable is not accessible by Lua by default.     luaL_getmetatable(l, "luaL_Foo");       // The Lua stack at this point looks like this:     //         //     3| metatable "luaL_foo"   |-1     //     2| userdata               |-2     //     1| string parameter       |-3     //     // So the following line sets the metatable for the user data to the luaL_Foo     // metatable     //     // We must set the metatable here because Lua prohibits setting     // the metatable of a userdata in Lua. The only way to set a metatable     // of a userdata is to do it in C.     lua_setmetatable(l, -2);       // The Lua stack at this point looks like this:     //         //     2| userdata               |-1     //     1| string parameter       |-2     //     // We return 1 so Lua callsite will get the user data and     // Lua will clean the stack after that.       return 1; }   Foo * l_CheckFoo(lua_State * l, int n) {     // This checks that the argument is a userdata     // with the metatable "luaL_Foo"     return *(Foo **)luaL_checkudata(l, n, "luaL_Foo"); }   int l_Foo_add(lua_State * l) {     Foo * foo = l_CheckFoo(l, 1);     int a = luaL_checknumber(l, 2);     int b = luaL_checknumber(l, 3);       std::string s = foo->Add(a, b);     lua_pushstring(l, s.c_str());       // The Lua stack at this point looks like this:     //         //     4| result string          |-1     //     3| metatable "luaL_foo"   |-2     //     2| userdata               |-3     //     1| string parameter       |-4     //     // Return 1 to return the result string to Lua callsite.       return 1; }   int l_Foo_destructor(lua_State * l) {     Foo * foo = l_CheckFoo(l, 1);     delete foo;       return 0; }   void RegisterFoo(lua_State * l) {     luaL_Reg sFooRegs[] =     {         { "new", l_Foo_constructor },         { "add", l_Foo_add },         { "__gc", l_Foo_destructor },         { NULL, NULL }     };       // Create a luaL metatable. This metatable is not     // exposed to Lua. The "luaL_Foo" label is used by luaL     // internally to identity things.     luaL_newmetatable(l, "luaL_Foo");       // Register the C functions _into_ the metatable we just created.     //luaL_register(l, NULL, sFooRegs);    luaL_setfuncs(l, sFooRegs, 0);
    // The Lua stack at this point looks like this:     //         //     1| metatable "luaL_Foo"   |-1     lua_pushvalue(l, -1);       // The Lua stack at this point looks like this:     //         //     2| metatable "luaL_Foo"   |-1     //     1| metatable "luaL_Foo"   |-2       // Set the "__index" field of the metatable to point to itself     // This pops the stack     lua_setfield(l, -1, "__index");       // The Lua stack at this point looks like this:     //         //     1| metatable "luaL_Foo"   |-1       // The luaL_Foo metatable now has the following fields     //     - __gc     //     - __index     //     - add     //     - new       // Now we use setglobal to officially expose the luaL_Foo metatable     // to Lua. And we use the name "Foo".     //     // This allows Lua scripts to _override_ the metatable of Foo.     // For high security code this may not be called for but     // we'll do this to get greater flexibility.     lua_setglobal(l, "Foo"); }   int main() {     lua_State * l = luaL_newstate();     luaL_openlibs(l);     RegisterFoo(l);       int erred = luaL_dofile(l, "fun.lua");     if(erred)         std::cout << "Lua error: " << luaL_checkstring(l, -1) << std::endl;       lua_close(l);       return 0; }

 

 

 

 

■ fun.lua 파일명으로 저장

-- fun.lua
 
-- Because the metatable has been exposed 
-- to us, we can actually add new functions
-- to Foo
function Foo:speak()
    print("Hello, I am a Foo")
end
 
local foo = Foo.new("fred")
local m = foo:add(3, 4)
 
-- "fred: 3 + 4 = 7"
print(m)
 
-- "Hello, I am a Foo"
foo:speak()
 
-- Let's rig the original metatable
Foo.add_ = Foo.add
function Foo:add(a, b)
    return "here comes the magic: " .. self:add_(a, b)
end
 
m = foo:add(9, 8)
 
-- "here comes the magic: fred: 9 + 8 = 17"
print(m)
 

 

 

■ 0x01.bind.cpp 컴파일 후 실행

g++ -o 0x01.bind 0x01.bind.cpp -I/usr/include/lua5.2/  -llua5.2 -lm

 ./0x01.bind 

 

 

 

반응형