lua-users home
lua-l archive

Re: [BUG] Re: A luaL_Buffer question

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


2017年11月02日 12:54 GMT+02:00 Viacheslav Usov <via.usov@gmail.com>:
> On Thu, Nov 2, 2017 at 8:41 AM, Marc Balmer <marc@msys.ch> wrote:
>
>> Is it possible to create a luaL_Buffer over several calls to Lua
>> functions? E.g. like in the following pseudo code:
>
> [...]
>
>> Or must all buffer operations be finished when I return from C code?
> I am unsure why such a dangerous facility is present, but I think that its
> dangers should be stressed by stronger language. The problem is that the
> crash happens only when large strings are stuffed into the buffer, which is
> a perfect ingredient for "it works when I test it, but it crashes randomly
> in production, and no one knows why".
It is there for greater efficiency.
> I think it can also be made less dangerous by using a reference to the
> userdatum rather than the top of the stack, but frankly, I think this is
> something that should only be used by Lua itself and its public use
> deprecated.
Oh, that is overstating the case. The public (or at least that section
of it that can write code in the Lua C API) is not so delicate.
What I envisaged in my earlier reply is in fact quite easy, almost
trivial. See attachment. (Lua 5.3).
/* buffer.c © Dirk Laurie 2017 MIT license like Lua 
 Compile with: cc -shared buffer.c -o buffer.so
 If you get a message containing the hint "recompile with -fPIC"., obey it.
 I.e.
 cc -shared buffer.c -fPIC -o buffer.so 
 Exercise for the reader: add a Lua front-end that allows object-oriented
 calls. i.e. buf:append(item) instead of buffer.append(buf,item) etc. 
 The metatable is already there. */
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
static int buffer_new (lua_State *L) {
 lua_newuserdata(L,sizeof(luaL_Buffer));
 luaL_buffinit(L, (luaL_Buffer*) lua_topointer(L,-1));
 luaL_setmetatable(L,"Buffer");
 return 1;
}
static int buffer_flush (lua_State *L) {
 luaL_Buffer* buf = (luaL_Buffer*) luaL_checkudata(L,1,"Buffer");
 luaL_pushresult(buf);
 return 1; 
}
static int buffer_append (lua_State *L) {
 luaL_Buffer* buf = (luaL_Buffer*) luaL_checkudata(L,1,"Buffer");
 luaL_addvalue(buf);
 return 0; 
}
static const luaL_Reg buffer_funcs[] = {
 {"new", buffer_new},
 {"flush", buffer_flush},
 {"append", buffer_append},
 {NULL, NULL}
};
LUAMOD_API int luaopen_buffer (lua_State *L) {
 luaL_newmetatable (L, "Buffer");
 luaL_newlib(L, buffer_funcs);
 return 1;
}

AltStyle によって変換されたページ (->オリジナル) /