ffi namespace not found after calling luaopen_ffi - c++

I have a C++ program that creates will create a lua_State and invoke custom lua code. Before calling the custom lua function, luaopen_ffi() is called with the lua_State:
luaopen_ffi(lua_state_);
However, when my program execute the custom lua code, it cannot find ffi. I further print out the value of ffi, and sadly it's nil instead:
print(ffi) --- which outputs nil
while other libraries loaded using luaopen does have a non-nil value, for instance
print(io) --- outputs table: 0x400af268
I further checked the source code of luaopen_ffi, it says it does not create a global ffi namespace based on its comment:
LUALIB_API int luaopen_ffi(lua_State *L) {
CTState *cts = lj_ctype_init(L);
settabV(L, L->top++, (cts->miscmap = lj_tab_new(L, 0, 1)));
cts->finalizer = ffi_finalizer(L);
LJ_LIB_REG(L, NULL, ffi_meta);
/* NOBARRIER: basemt is a GC root. */
setgcref(basemt_it(G(L), LJ_TCDATA), obj2gco(tabV(L->top-1)));
LJ_LIB_REG(L, NULL, ffi_clib);
LJ_LIB_REG(L, NULL, ffi_callback);
/* NOBARRIER: the key is new and lj_tab_newkey() handles the barrier. */
settabV(L, lj_tab_setstr(L, cts->miscmap, &cts->g->strempty), tabV(L->top-1));
L->top--;
lj_clib_default(L, tabV(L->top-1)); /* Create ffi.C default namespace. */
lua_pushliteral(L, LJ_OS_NAME);
lua_pushliteral(L, LJ_ARCH_NAME);
LJ_LIB_REG(L, NULL, ffi); /* Note: no global "ffi" created! */
ffi_register_module(L);
return 1;
}
I also tried ffi = require("ffi") and it does not work :(.
So can I know how can I use ffi features after calling luaopen_ffi? Or luaopen_ffi is not the correct way?

If you want a global named ffi, try this:
luaopen_ffi(lua_state_);
lua_setglobal(lua_state_ ,"ffi");
It seems that luaopen_ffi leaves the table on the stack, as is usual in Lua modules.

Related

Lua: fails to get field after loading a second string;

Good afternoon,
I am working on a LUA/C++ application, from which i need lua to be able to call other lua code recursively, e.g: C++ calls lua function, lua function calls another lua function from another string that is loaded using a registered C function that runs at the start of the first lua function;
here are the steps i am following:
lua_State* state = luaL_newstate();
luaL_openlibs(state);
lua_register(state, "secondLua", secondLua);
lua_getfield( _luaState, LUA_GLOBALSINDEX, "init" );
lua_pcall( _luaState, 0, 0, 0 );
int secondLua(lua_State* state){
char* myString[128] = "function init2()\n io.write(\"hello\")\n end";
luaL_loadstring(pLuaState, myString);
lua_getfield(pLuaState,LUA_GLOBALSINDEX, "init2"); // function init2 declared on myString
lua_pcall(pLuaState, 0, LUA_MULTRET, 0);
//getting "attempt to call a nil value" here
return 0;
}
Any help is appreciated, and second, i would like to know if there is a way i can name the second function "init" as well as the first one;
PS: I am using C++14 and lua 5.1 on LUAJIT, and i cant use lua's dofile;
lua_loadstring() compiles supplied source and puts Lua chunk on stack. It won't execute it though, so init2() still not defined when you expect that.
Replace lua_loadstring() with luaL_dostring() to actually run that chunk and define new lua functions. Or call lua_pcall() right after lua_loadstring(). Actually, luaL_dostring() does exactly that - lua_loadstring() followed by lua_pcall().

How to replace Lua default error print?

I'm implementing Lua as a script language into a Windows application. Due to the application's structure, printout isn't using streamed io, such as stdout and stderror.
I have managed to override the Lua print to fit into my structure...
lua_register(L,"print", cs_print);
...but how do I override all error an debug printouts without using streams? I need to handle this in a function (similar to print).
The only place where Lua writes to stderr is in the panic function that luaL_newstate installs. If you're embedding Lua into your application, make sure you start Lua from a protected call and no panic will ever occur. See http://www.lua.org/source/5.2/lua.c.html#main for ideas.
After a lot of Google I came up with this solution to fetch compiler and runtime error messages as well to redirect the standar Lua print function.
I use C++ Builder but I think it can be useful for anyone looking for the same answer.
The script is running in a TScriptLua object instance and to map a Lua state against the correct script instance, I use a std::map list to look up the object pointer.
// list for mapping Lua state with object pointers.
static std::map<lua_State*,TScriptLua*> LuaObjMap;
Next is an inline function to get the object pointer from a Lua state pointer.
extern "C" {
// Inline to map Lua state pointer to object pointer
static inline TScriptLua* GetScriptObject(lua_State* L) {
return LuaObjMap.find(L)->second;
}
This function will replace the standard Lua print function. The object pointer (f) has a member function in its base class called Out() that will output a char buffer in the associated window control.
// New Lua print function
static int cs_print (lua_State *L) {
// Map Lua state to object
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); // Get string
size_t len = lua_rawlen(L,i); // Get string length
// Output string.
f->Out(str,len);
}
}
return 0;
}
This is my error print routine that will display the compiler/runtime error. As for the Lua print function, the f->Out is used again to print the error message.
// Error print routine
static int cs_error(lua_State *L, char *msg) {
// Map Lua state to object
TScriptLua* f = GetScriptObject(L);
// Get error message
AnsiString m = String(msg) + " " + String(lua_tostring(L, -1));
// "print" error message
f->Out(m.c_str(),m.Length());
// Clenaup Lua stack
lua_pop(L, 1);
return 0;
}
} // <--- End extern C
Here is the actual load and run member. After the new Lua state has been created it is associated with this object in the mapping list. Then it loads the script from a Rich edit control with luaL_loadbuffer(), checks for compiler errors and runs the compiled script with lua_pcall().
void __fastcall TScriptLua::Compile(void) {
// Create new Lua state
lua_State *L = luaL_newstate();
// Store mapping Lua state --> object
LuaObjMap.insert( std::pair<lua_State*,TScriptLua*>(L,this) );
// Override Lua Print
lua_register(L,"print", cs_print);
// Load and compile script
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)) // Run loaded Lua script
cs_error(L, "Runtime error: "); // Print runtime error
} else {
cs_error(L, "Compiler error: "); // Print compiler error
}
// Close Lua state
lua_close(L);
// Remove Lua --> object mapping
LuaObjMap.erase( LuaObjMap.find(L) );
}
This isn't my final solution, but it does the trick so far. I think the best thing is to write stream handling into the TScriptLua object so I can register it directly into Lua.

Accessing Lua variable in function environment from C++

This is probably an easy question, but I am stumped. This is for Lua 5.1.
I have a script which runs in its own environment. In that environment, I have a variable called "plugin" I set from C++ like so:
lua_getfield(L, LUA_REGISTRYINDEX, getScriptId()); // Put script's env table onto the stack -- env_table
lua_pushstring(L, "plugin"); // -- env_table, "plugin"
luaW_push(L, this); // -- env_table, "plugin", *this
lua_rawset(L, -3); // env_table["plugin"] = *this -- env_table
lua_pop(L, -1); // Cleanup -- <<empty stack>>
Before running my Lua script, I set the function environment like so:
lua_getfield(L, LUA_REGISTRYINDEX, getScriptId()); // Push REGISTRY[scriptId] onto stack -- function, table
lua_setfenv(L, -2); // Set that table to be the env for function -- function
When my script runs, it can see and interact with the plugin variable, as expected. So far, so good.
At one point, the Lua script calls a C++ function, and in that function, I want to see if the plugin variable is set.
I have tried many many things, and I can't seem to see the plugin variable. Here are but 4 things I tried:
lua_getfield(L, LUA_ENVIRONINDEX, "plugin");
bool isPlugin = !lua_isnil(L, -1);
lua_pop(L, 1); // Remove the value we just added from the stack
lua_getfield(L, LUA_GLOBALSINDEX, "plugin");
bool isPlugin2 = !lua_isnil(L, -1);
lua_pop(L, 1); // Remove the value we just added from the stack
lua_getglobal(L, "plugin");
bool isPlugin3 = !lua_isnil(L, -1);
lua_pop(L, 1); // Remove the value we just added from the stack
lua_pushstring(L, "plugin");
bool isPlugin4 = lua_isuserdata(L, -1);
lua_pop(L, 1);
Unfortunately, all the isPlugin variables return false. It is as if the C++ function called from Lua cannot see a variable set in a Lua environment.
Any idea how I can see the plugin variable from C++?
Thanks!
Every function in Lua has it's own environment. They don't inherit the environment of whomever calls them. So if your C++ function doesn't use the environment that has this plugin variable, then it won't see it.
You could pass the environment to the C function as part of the closure (see lua_pushcclosure). I don't know the kind of setup you have, but I can see three ways this can pan out:
1) Your C function is registered in the same environment as the function - good, will work.
2) Your C function is registered in the global environment but the Lua functions which will call it all reside in one specific environment - will still work if the environment exists when the function is registered (so it can be added to the closure).
3) Your C function is registered in the global environment and can be called by different Lua functions working in different environments - will not work anymore.
If it's 2 or 3, there might be no drawbacks if you change the implementation to use variant 1.
Edit: Alright, so that won't work. There is a way to obtain under-the-hood information if you are willing to stray a bit from the Lua API. DISCLAIMER: I am working with 5.2, so I am trying to adapt my methods for 5.1. I could not test this, and it might not work.
First you will need to #include "lstate.h"
This is the lua_State structure in 5.1:
struct lua_State {
CommonHeader;
lu_byte status;
StkId top; /* first free slot in the stack */
StkId base; /* base of current function */
global_State *l_G;
CallInfo *ci; /* call info for current function */
const Instruction *savedpc; /* `savedpc' of current function */
StkId stack_last; /* last free slot in the stack */
StkId stack; /* stack base */
CallInfo *end_ci; /* points after end of ci array*/
CallInfo *base_ci; /* array of CallInfo's */
int stacksize;
int size_ci; /* size of array `base_ci' */
unsigned short nCcalls; /* number of nested C calls */
lu_byte hookmask;
lu_byte allowhook;
int basehookcount;
int hookcount;
lua_Hook hook;
TValue l_gt; /* table of globals */
TValue env; /* temporary place for environments */
GCObject *openupval; /* list of open upvalues in this stack */
GCObject *gclist;
struct lua_longjmp *errorJmp; /* current error recover point */
ptrdiff_t errfunc; /* current error handling function (stack index) */
};
Let's assume L is your lua_State*.
As you can see, L->ci holds the current callinfo, and the callinfo array is contained between L->base_ci and L->end_ci.
So the Lua function which called your C function is situated at (L->end_ci-2) (which should be the same as (L->ci-1)), and its stack id (StkId) is (L->end_ci-2)->func.
We can trick the Lua API into letting you work with stack ids which are below the current calling function by doing something like this:
StkId saved = L->base;
L->base = L->base_ci->base;
int idx = (L->end_ci-2)->func - L->base+1;
lua_getfenv(L, idx);
L->base = saved;
The environment table should be on top of the stack now.
Edit: The Lua API checks for a valid index are a bit tricky. This should fool them.

how do I extend Lua with a static c++ library?

I have a Visual Studio 2008 C++03 application that uses Lua 5.2.1. I would like to extend Lua with a module called "foo", but when I call require("foo") in my Lua script, I get the error:
foo_test.lua:1: module 'foo' not found:
no field package.preload['process']
no file '!\lua\process.lua'
no file '!\lua\process\init.lua'
no file '!\process.lua'
no file '!\process\
My Lua script:
foo.bar()
My lua_foo.h file:
#include <lua.h>
extern "C" int luaopen_foo( lua_State* L );
My lua_foo.cpp file:
#include "lua_foo.h"
#include <lua.hpp>
static int l_bar( lua_State *L )
{
puts( "in bar()" );
return 1;
}
int luaopen_foo( lua_State *L )
{
static const luaL_Reg foo[] = {
{ "bar", l_bar },
{ NULL, NULL }
};
luaL_newlib( L, foo );
return 1;
}
These are compiled in to a static library "lua_foo.lib" which is statically linked to my main Lua executable.
Can anybody help me understand where I'm going wrong? thanks. I would prefer to avoid c++ wrappers (for now) and I do not want to package this library as a separate DLL from the main Lua engine.
EDIT
The issue was in the lua engine code. I added the luaL_requiref per #NicolBolas 's suggestion.
lua_State* L = luaL_newstate();
if( NULL != L )
{
luaL_openlibs( L );
luaL_requiref( token.get(), "foo", luaopen_foo, 1 );
luaL_dofile( L, "foo_test.lua" );
lua_close( L );
}
It's important to understand how the require machinery works and therefore why your code doesn't.
require is designed to look for Lua scripts in the file system and DLLs. Static libraries are not DLLs; indeed, as far as C/C++ is concerned, once you've finished linking, static libraries are no different than compiling those .c/.cpp files into your application directly.
When require finds a DLL with the appropriate name, it loads it and attempts to find a function named luaopen_<modname>, where <modname> is the name of the module. When it does, it will execute this function and store the value it returns in an internal database of loaded modules.
Calling require for a module will return whatever this function returned; if the module has already been loaded, then the return value is pulled from the database and returned directly.
Simply calling luaopen_foo will not do any of this. Indeed, simply calling this function is a bad idea; it is a Lua function and needs to be called as a Lua function (ie: you need to push it onto the Lua stack with lua_pushcfunction and call it with lua_call and so forth).
If you want to create a local module (one not in a Lua script or DLL, but exposed from your code), then you need to use the Lua facilities to do that. Specifically, use luaL_requiref:
luaL_requiref(L, "foo", luaopen_foo, 0);
Call this instead of calling luaopen_foo directly. This will automatically register the return value from luaopen_foo with require's internal database of loaded modules. Thus, subsequent calls to require "foo" will return this table.
One more thing: do is a keyword in Lua; you should not use keywords for Lua table key names. You can, but you always have to quote them (ie: your script must do foo["do"](...) to call it).
luaopen_foo creates a table with one function in it, but it doesn't expose it to Lua in any way. You need to assign it to something your scripts can access if you want to access it. You can do this with the package mechanism, or just assign it to a global (which is what Lua's built-in libraries do).
You have a field named do, which is problematic if you want to use foo.do syntax, because do is a keyword.
The return value of a Lua function tells Lua how many values you left on the stack. Your l_do function lies with its return value.
In the case of luaopen_foo, since you're calling it directly and ignoring it's return value, there's no need for it to return anything at all.
Change your code to this:
static int l_bar( lua_State *L )
{
puts("l_bar called.");
return 0;
}
void luaopen_foo( lua_State *L )
{
static const struct luaL_Reg foo[] = {
{ "bar", l_bar },
{ NULL, NULL }
};
luaL_newlib( L, foo ); // create table containing `bar`
lua_setglobal(L, "foo"); // assign that table to global `foo`
}
And change your script to this:
foo.bar()

Redirecting/redefining print() for embedded Lua

I have embedded Lua in my C++ application. I want to redirect print statements (or maybe simply redefine the print function?), so that I can display the evaluated expression somewhere else.
What is the best way to do this: redirect or redefining the print() function?
Any snippets/pointers to snippets that show how to do this would be much appreciated.
You can redefine the print statement in C:
static int l_my_print(lua_State* L) {
int nargs = lua_gettop(L);
for (int i=1; i <= nargs; i++) {
if (lua_isstring(L, i)) {
/* Pop the next arg using lua_tostring(L, i) and do your print */
}
else {
/* Do something with non-strings if you like */
}
}
return 0;
}
Then register it in the global table:
static const struct luaL_Reg printlib [] = {
{"print", l_my_print},
{NULL, NULL} /* end of array */
};
extern int luaopen_luamylib(lua_State *L)
{
lua_getglobal(L, "_G");
// luaL_register(L, NULL, printlib); // for Lua versions < 5.2
luaL_setfuncs(L, printlib, 0); // for Lua versions 5.2 or greater
lua_pop(L, 1);
}
Since you are using C++ you'll need to include your file using 'extern "C"'
You can simply redefine print from a Lua script.
local oldprint = print
print = function(...)
oldprint("In ur print!");
oldprint(...);
end
See luaB_print in lbaselib.c. The comment there reads:
/* If you need, you can define your own `print' function, following this
model but changing `fputs' to put the strings at a proper place (a
console window or a log file, for instance). */
You can just edit that function or define a new one. This has the advantage of being simple and portable, but it won't handle io.write (which you may or may not care about).
Redirecting IO isn't going to be platform specific (such as SetStdHandle in Windows), but will take care of print and io.write without redefining either.
Write your own C or Lua function and redefine print.
You can just redefine the following macros:
lua_writestring
lua_writeline
lua_writestringerror
to whatever you like.
I'm not sure about the lua version where this was introduced - but it works in 5.3 for me.
Check your lauxlib.h or luaconf.h.