2012-03-05 2 views
1

나는 동적으로 Lua 명령을 생성하고 소켓으로 클라이언트에 보내는 C 서버에서 작업하고 있습니다. 현재 서버는 일반 텍스트를 사용하고 있지만 클라이언트에게 보내기 전에 서버에서 스크립트를 미리 컴파일하고 싶습니다.Lua 스크립트를 서명되지 않은 char 버퍼로 컴파일

나는 luac.c을 확인하지만, 이런 식으로 뭔가를 할 수있을하는 방법을 찾을 수 없습니다 :

char lua_commands[ 1024 ] = { "a = 123; b = 456; c = a + b;" }; 

int socket 
unsigned int send_buffer_size 
unsigned char *send_buffer 

/* Compile lua_commands and store the binary script into send_buffer without 
having to write first the .out on disk then read it again in order store the content 
into send_buffer */ 

send(socket, send_buffer, send_buffer_size, 0); 

누구는 이것을 달성하는 데 도움이 수 있습니까?

[업데이트]

좋아, 나는 그것을 알아낼 생각 :

#include "lua.h" 
#include "lauxlib.h" 
#include "ldo.h" 
#include "lfunc.h" 
#include "lmem.h" 
#include "lobject.h" 
#include "lopcodes.h" 
#include "lstring.h" 
#include "lundump.h" 


#define toproto(L,i) (clvalue(L->top+(i))->l.p) 

static int writer(lua_State *L, const void *p, size_t size, void *u){ 

    unsigned int i = 0; 

    unsigned char *d = (unsigned char *)p; 

    // Print all the bytes on the console. 
    while(i != size) { 
     printf("%d ", d[ i ]); 
     ++i; 
    } 
    return 0; 
} 


void compile(lua_State *L, char *command){ 

    const Proto* f; 

    if (luaL_loadstring(L, command) !=0) { 
     printf("%s\n", lua_tostring(L, -1)); 
    } 

    f = toproto(L,-1); 

    lua_lock(L); 

    luaU_dump(L, f, writer, NULL, 1); 

    lua_unlock(L);  
} 


int main (int argc, const char * argv[]) { 

    lua_State *L = lua_open(); 

    compile(L, "a = 123; b = 456; c = a + b; print(c);"); 

    lua_close(L); 

    return 0; 
} 

그러나 다른 질문에 날 리드하는 내가 루아 상태를 닫고 (lua_close, lua_open) 다시해야합니까 매번 다른 Lua 명령어로 컴파일() 함수를 호출하거나 출력은 최신 luaL_loadstring의 결과 일뿐입니다?

Im 확실하지 않지만 toproto 매크로 정의에서 최상위 스택이 반환 될 것이라고 생각합니까?

+4

가능한 복제본 [컴파일 루아 코드, 저장 바이트 코드,로드 및 실행] (http://stackoverflow.com/questions/8936369/compile-lua-code-store-bytecode-then-load-and-execute- it) –

+2

바이트 코드보다는 루아 소스 텍스트에 메시지를 남기는 것이 여러 가지 이점을 가질 수 있음에 유의하십시오. 내 머리 꼭대기에서 ... 우선, 바이트 코드는 종종 작지 않습니다. 둘째, 바이트 코드는 플랫폼에 따라 다릅니다. 셋째, 바이트 코드는 안전하다고 확인하기가 매우 어렵습니다. 크기가 중요한 경우 짧은 식별자, 최소 공백 및 주석없이 항상 메시지를 생성 할 수 있습니다. 또한 큰 메시지에 도움이되는 유선에서 압축을 사용할 수도 있습니다. – RBerteig

답변

0

내부에 toproto() + luaU_dump() 기능 대신 lua_dump()을 사용해야합니다. 추가 보너스로이 코드는 LuaJIT 2을 지원합니다.

덤프를 얻을 때마다 상태를 다시 만들 필요가 없습니다.

그러나. 신뢰할 수없는 출처의 서버에서 실행되는 Lua 바이트 코드는 실행하지 않는 것이 좋습니다 (서버는 종종 이 클라이언트에게는 신뢰되지 않습니다.)입니다. 안전하지 않습니다. 및 심각한 보안 문제가 발생할 수 있습니다. (이러한 소스 코드에 문제가 없습니다 -하지만 당신은 여전히 ​​물론, 그것을 샌드 박스에 있습니다.) 일반적으로

, 항상 당신이 코드는 신뢰할 수없는 소스가 바이트 코드가 하지에서로드되었는지 확인 있는지 확인 (첫 번째 바이트가 27 십진수이면). 항상은 이러한 코드 in a sandbox을 실행합니다.


필요한 경우 루아 우호적 인 방식으로 데이터를 전달하는 것이므로 적절한 데이터 직렬화 라이브러리를 대신 선택하십시오. 샌드 박스 및 이식성 문제 외에도 loadstring()은 다소 느립니다.

예를 들어 우리는 비슷한 목적으로 라이브러리를 사용하고 있습니다 (다른 방법으로는 this list에 구멍을 뚫어주십시오). Luatexts는 튜플을 지원합니다. 튜플은 함수 호출로 훌륭하게 작동합니다. (의사의) 예를 들면 :

서버 :

my_send(luatexts.lua.save("myMethod", { param = true }, 42)) 

클라이언트 :

local actions = { } 

function actions.myMethod(params, number) 
    print(params.param, number) --> true, 42 
end 

local function handle_action(ok, name, ...) 
    assert(ok, name) -- name would contain error message if not OK 
    local handler = assert(actions[name], "unknown action") 
    return handler(...) 
end 

local str = my_receive() 

handle_action(luatexts.load(str)) 

오픈 티켓은 luatexts.save를 원하거나 지원이 C로 구현 스트리밍하는 경우

+0

'toproto()'+'luaU_dump()'대신'lua_dump()'를 사용하는 것에 대한 인자를 추가해 주실 수 있습니까? 기본적으로 디버그 정보를 제거하지는 않습니다. – Kamiccolo

+0

일반적으로 다른 라이브러리의 개인 내부뿐만 아니라 사적인 루아 내부 구조를 직접 사용하면 안됩니다. 해킹하고 사용하려는 경우 - 스스로 해결할 수 있습니다. –

+0

공용 인터페이스가 라이브러리의 정확한 필요에 맞는 경우에만 동의합니다. 내 경우에는 그렇지 않습니다. 최악의 상황 - 가까운 장래에 더 잘 맞을 것입니다. Lua 라이브러리가 OpenSource 인 반면 정확한 프로젝트에 필요한 기능을 얻으려면 해킹하는 것이 좋습니다. Btw, LuaJIT 인수가 좋다. 하지만 작은. 그 중 일부는 더 듣고 싶습니다 :) – Kamiccolo

관련 문제