编译Lua脚本为无符号字符缓冲区。

我正在使用C语言编写一个服务器,可以动态生成Lua命令并通过套接字发送给客户端。目前服务器正在使用纯文本,但我希望服务器在将脚本发送到客户端之前进行预编译。

我查看了luac.c但无法找到如何能够执行以下操作的方法:

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

int socket
unsigned int send_buffer_size
unsigned char *send_buffer

/*将lua_commands编译并将二进制脚本存储到send_buffer中,而不必先将.out写入磁盘,然后再读取它以便将内容存储到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命令调用compile()函数时,我是否必须关闭和重新打开(lua_open,lua_close)Lua状态,或者输出只有最新的luaL_loadstring的结果?

我不确定,但从toproto宏定义中看,最高的堆栈将被返回,我正确吗?

原文链接 https://stackoverflow.com/questions/9562129

点赞
stackoverflow用户6236
stackoverflow用户6236

你应该使用 lua_dump() 而不是 toproto()luaU_dump() 这些内部函数。这样做的好处是,你的代码可以支持 LuaJIT 2

每次获取 dump 时重新创建状态是不必要的。

但是。 我建议避免执行来自不受信任的源(而服务器通常是不可信的),生成的 Lua 字节码。这是不安全的,并可能导致严重的安全问题。(源代码没有这样的问题,但你仍然需要对其进行沙箱处理。)

一般来说,始终确保检查从不可信来源加载的代码是否不是字节码(如果第一个字节是十进制的 27 就是字节码)。始终在沙箱中执行此类代码。


如果你只是需要以友好的 Lua 方式传递数据,那么选择一些合适的数据序列化库就可以了。除了沙箱和可移植性问题外,loadstring()也相当慢。

例如,我们正在使用我的 luatexts 库进行类似的用途(确保查看 这个列表 以获取替代方案)。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 将包含错误消息
  local handler = assert(actions[name], "unknown action")
  return handler(...)
end

local str = my_receive()

handle_action(luatexts.load(str))

如果想要在 C 中实现 luatexts.save 或流支持,可以打开一个工单。

2012-05-05 04:16:11