NOTE: THIS IS A LOW-LEVEL EXAMPLE, using pieces of sol2 to facilitate better usage It is recommended you just do the simple version, as it is basically this code but it is sometimes useful to show the hoops you need to jump through to use the Lua C API
| 24 | // basically this code but it is sometimes useful to show the |
| 25 | // hoops you need to jump through to use the Lua C API |
| 26 | void complicated(sol::this_state ts) { |
| 27 | lua_State* L = ts; |
| 28 | |
| 29 | lua_Debug info; |
| 30 | // Level 0 means current function (this C function, which is |
| 31 | // useless for our purposes) Level 1 means next call frame |
| 32 | // up the stack. This is probably the environment we're |
| 33 | // looking for? |
| 34 | int level = 1; |
| 35 | int pre_stack_size = lua_gettop(L); |
| 36 | if (lua_getstack(L, level, &info) != 1) { |
| 37 | // failure: call it quits |
| 38 | std::cout << "error: unable to traverse the stack" |
| 39 | << std::endl; |
| 40 | lua_settop(L, pre_stack_size); |
| 41 | return; |
| 42 | } |
| 43 | // the "f" identifier is the most important here |
| 44 | // it pushes the function running at `level` onto the stack: |
| 45 | // we can get the environment from this |
| 46 | // the rest is for printing / debugging purposes |
| 47 | if (lua_getinfo(L, "fnluS", &info) == 0) { |
| 48 | // failure? |
| 49 | std::cout << "manually -- error: unable to get stack " |
| 50 | "information" |
| 51 | << std::endl; |
| 52 | lua_settop(L, pre_stack_size); |
| 53 | return; |
| 54 | } |
| 55 | |
| 56 | // Okay, so all the calls worked. |
| 57 | // Print out some information about this "level" |
| 58 | std::cout << "manually -- [" << level << "] " |
| 59 | << info.short_src << ":" << info.currentline |
| 60 | << " -- " << (info.name ? info.name : "<unknown>") |
| 61 | << "[" << info.what << "]" << std::endl; |
| 62 | |
| 63 | // Grab the function off the top of the stack |
| 64 | // remember: -1 means top, -2 means 1 below the top, and so |
| 65 | // on... 1 means the very bottom of the stack, 2 means 1 |
| 66 | // more up, and so on to the top value... |
| 67 | sol::function f(L, -1); |
| 68 | // The environment can now be ripped out of the function |
| 69 | sol::environment env(sol::env_key, f); |
| 70 | if (!env.valid()) { |
| 71 | std::cout << "manually -- error: no environment to get" |
| 72 | << std::endl; |
| 73 | lua_settop(L, pre_stack_size); |
| 74 | return; |
| 75 | } |
| 76 | sol::state_view lua(L); |
| 77 | sol::environment freshenv = lua["freshenv"]; |
| 78 | bool is_same_env = freshenv == env; |
| 79 | std::cout << "manually -- env == freshenv : " << is_same_env |
| 80 | << std::endl; |
| 81 | } |
| 82 | |
| 83 | int main() { |