#define SOL_CHECK_ARGUMENTS 1 #include // Something that can't be collided with constexpr static const auto& script_key = "GlobalResource.MySpecialIdentifier123"; struct GlobalResource { int value = 2; }; // Customize sol2 to handle this type namespace sol { template <> struct lua_type_of : std::integral_constant {}; namespace stack { template <> struct checker { template static bool check(lua_State* L, int /*index*/, Handler&& handler, record& tracking) { tracking.use(0); // get the field from global storage stack::get_field(L, script_key); // verify type type t = static_cast(lua_type(L, -1)); lua_pop(L, 1); if (t != type::lightuserdata) { handler(L, 0, type::lightuserdata, t, "global resource is not present"); return false; } return true; } }; template <> struct getter { static GlobalResource* get(lua_State* L, int /*index*/, record& tracking) { // retrieve the (light) userdata for this type tracking.use(0); // not actually pulling anything off the stack stack::get_field(L, script_key); GlobalResource* ls = static_cast(lua_touserdata(L, -1)); lua_pop(L, 1); // clean up stack value returned by `get_field` return ls; }; }; template <> struct pusher { static int push(lua_State* L, GlobalResource* ls) { // push light userdata return stack::push(L, make_light(ls));; } }; } } int main() { sol::state lua; lua.open_libraries(sol::lib::base); GlobalResource instance; // get GlobalResource lua.set_function("f", [](GlobalResource* l, int value) { return l->value + value; }); lua.set(script_key, &instance); // note only 1 argument, // despite being 2 lua.script("assert(f(1) == 3)"); return 0; }