After a lot of Google, I came up with this solution to extract compiler and runtime error messages, and also to redirect the standard Lua print function.
++ Builder, , , .
script TScriptLua Lua script, std:: map .
static std::map<lua_State*,TScriptLua*> LuaObjMap;
- Lua.
extern "C" {
static inline TScriptLua* GetScriptObject(lua_State* L) {
return LuaObjMap.find(L)->second;
}
Lua. (f) - Out(), char .
static int cs_print (lua_State *L) {
TScriptLua* f = GetScriptObject(L);
if (f) {
int count = lua_gettop(L);
for (int i=1; i <= count; ++i) {
const char *str = lua_tostring(L, i);
size_t len = lua_rawlen(L,i);
f->Out(str,len);
}
}
return 0;
}
, / . Lua, f- > Out .
static int cs_error(lua_State *L, char *msg) {
TScriptLua* f = GetScriptObject(L);
AnsiString m = String(msg) + " " + String(lua_tostring(L, -1));
f->Out(m.c_str(),m.Length());
lua_pop(L, 1);
return 0;
}
}
. Lua . script Rich Edit luaL_loadbuffer(), script lua_pcall().
void __fastcall TScriptLua::Compile(void) {
lua_State *L = luaL_newstate();
LuaObjMap.insert( std::pair<lua_State*,TScriptLua*>(L,this) );
lua_register(L,"print", cs_print);
AnsiString script(Frame->Script_RichEdit->Text);
if (luaL_loadbuffer(L,script.c_str(),script.Length(),AnsiString(Name).c_str()) == 0) {
if (lua_pcall(L, 0, 0, 0))
cs_error(L, "Runtime error: ");
} else {
cs_error(L, "Compiler error: ");
}
lua_close(L);
LuaObjMap.erase( LuaObjMap.find(L) );
}
, . , TScriptLua, Lua.