我在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
/* 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命令调用我的compile()函数时,是否必须关闭并重新打开(lua_open,lua_close)Lua状态,否则输出只会是最新的luaL_loadstring?
我不确定,但是从toproto宏定义中看到我将返回最顶层的堆栈,我是否正确?
答案 0 :(得分:0)
您应该使用lua_dump()
而不是内部toproto()
+ luaU_dump()
功能。作为额外的好处,这样您的代码将支持LuaJIT 2。
每次获得转储时都没有必要重新创建状态。
BUT。我会避免执行来自不受信任来源的Lua字节码(而且服务器经常 不受信任到客户端)。 不安全,,可能会导致严重的安全问题。 (源代码没有这样的问题 - 当然,你仍然必须对它进行沙盒化。)
通常,总是确保您检查从不受信任的源加载的代码是不是字节码(如果是byte是27
十进制的)。 始终执行此类代码in a sandbox。
如果您只需要以Lua友好的方式传递数据,请选择一些正确的数据序列化库。除沙箱和可移植性问题外,loadstring()
相当慢。
例如,我们正在使用我的luatexts库进行类似的目的(确保通过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
或流媒体支持,请打开故障单。