1
votes

I am testing about calling LUA scripts from C. LUA 5.3.5.

To tighten the libraries used, in C I am using

L = luaL_newstate();
luaopen_base(L);
luaopen_string(L);
luaL_dofile(L, szFilename);
int tipo = lua_getglobal(L, "check");
int error = lua_pcall(L, 0, 0, 0);

(code simplified and without error handling)

This is the sample LUA script:

function check()
        local buffer = "hello"
        buffer = buffer .. " world!"
        print(buffer)
        print(string.len(buffer))
end

Why does string.len return error?

attempt to index a nil value (global 'string')

I thought luaopen_string loads the string library.

2

2 Answers

2
votes

luaopen_string does not define a global variable string: it just leaves the table on the stack. So do

luaopen_string(L);
lua_setglobal(L,"string");

Alternatively, use luaL_requiref instead of calling luaopen_string directly:

luaL_requiref(L,"string", luaopen_string,1);

See the last paragraph of section 6 in the manual;

To have access to these libraries, the C host program should call the luaL_openlibs function, which opens all standard libraries. Alternatively, the host program can open them individually by using luaL_requiref to call ... luaopen_string (for the string library) ... These functions are declared in lualib.h.

Finally, if you want to customize the set of standard libraries that your program uses, edit linit.c and add it to your project. Change the list in loadedlibs. Then call luaL_openlibs.

0
votes

After talking on the LUA mailing list, the best hint I got is to look at the source code.

luaL_openlibs is defined in linit.c

LUALIB_API void luaL_openlibs (lua_State *L) {
  const luaL_Reg *lib;
  /* "require" functions from 'loadedlibs' and set results to global table */
  for (lib = loadedlibs; lib->func; lib++) {
    luaL_requiref(L, lib->name, lib->func, 1);
    lua_pop(L, 1);  /* remove lib */
  }
}

So to load only the libraries base and string the solution for LUA 5.3 is

 luaL_requiref(L, "_G", luaopen_base, 1);
 lua_pop(L, 1);
 luaL_requiref(L, LUA_STRLIBNAME, luaopen_string, 1);
 lua_pop(L, 1);

And for LUA 5.4

 luaL_requiref(L, LUA_GNAME, luaopen_base, 1);
 lua_pop(L, 1);
 luaL_requiref(L, LUA_STRLIBNAME, luaopen_string, 1);
 lua_pop(L, 1);