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
requiremachinery works and therefore why your code doesn’t.requireis 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
requirefinds a DLL with the appropriate name, it loads it and attempts to find a function namedluaopen_<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
requirefor 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_foowill 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 withlua_pushcfunctionand call it withlua_calland 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:Call this instead of calling
luaopen_foodirectly. This will automatically register the return value fromluaopen_foowithrequire‘s internal database of loaded modules. Thus, subsequent calls torequire "foo"will return this table.One more thing:
dois 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 dofoo["do"](...)to call it).