Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fail to execute simple Lua code with kaguya #57

Open
CaillotKi opened this issue Jan 20, 2017 · 4 comments
Open

Fail to execute simple Lua code with kaguya #57

CaillotKi opened this issue Jan 20, 2017 · 4 comments

Comments

@CaillotKi
Copy link

Hi,

I've tried to compile and run some simple code using kaguya.
I compiled the same code twice, first with my system binary and
libraries (64 bits archlinux up to date) and then with a toolchain
for 32 bits x86.

In both cases the compilation is successful, my problem is when I run
the version compiled with the toolchain I get an error : "attempt to index a nil value"
(which I don't get with the version compiled directly with my system).

I tried to replicate the code logic using only the lua C api and then compiled
it again with my system binary and libraries then with the toolchain. In this
case both binaries works as expected.

My system uses g++ 6.2.1 while the toolchain is using g++ 4.9.2 (both meeting kaguya
requirements). I'm compiling with the std=c++11 option.
My system uses lua 5.3.3 while the toolchain uses 5.2.2

Here is the code which get me the "attempt to index a nil value" error :

     #include "kaguya.hpp"
    
     kaguya::State luaState;
 
     auto scriptAdding2CppVariables = R"(
         return valA + valB
     )";
 
     // Loading script in Lua context.
     kaguya::LuaFunction luaFunc = luaState.loadstring(scriptAdding2CppVariables);
 
     auto a = 1;
     auto b = 2;
 
     // Exporting variables to Lua context (under the same they're used in the previous script).
     luaState["valA"] = a;
     luaState["valB"] = b;
 
     if (luaFunc() == a + b)
     {
         std::cout << "SUCCESS" << std::endl;
     }
     else
     {
         std::cout << "FAILED" << std::endl;
     }

And here is the equivalent with the C api which does not trigger any error.

     #ifdef __cplusplus
     #include <lua.hpp>
     #else
     # include <lua.h>
     # include <lualib.h>
     # include <lauxlib.h>
     #endif

     lua_State* state;

    auto scriptAdding2CppVariables = R"(
        function add (varA, varB)
            return varA + varB
        end
     )";

     /* initialize Lua */
     state = luaL_newstate();

     luaL_dostring(state, scriptAdding2CppVariables);
     lua_getglobal(state, "add");

     auto varA = 1;
     lua_pushnumber(state, varA);

     auto varB = 2;
     lua_pushnumber(state, varB);

     lua_call(state, 2, 1);

     /* call the add function */
     auto sum = (int)lua_tointeger(state, -1);
     lua_pop(state, 1);

     if(sum == varA + varB)
     {
           std::cout << "SUCCESS" << std::endl;
     }
     else
     {
          std::cout << "FAILED" << std::endl;
     }

     /* cleanup Lua */
     lua_close(state);

I've tried modifying scriptAdding2CppVariables (in the code version using kaguaya) to
"return 1 + 2" and removed the statements to export the variables a and b into the lua
context but I still get the same error. It leaves us with only 3 statements using lua.
Commenting the call to luaFunc() does stop the error from occurring.

If anyone could tell me why I got this behavior I'd be grateful.

Thanks

@satoren
Copy link
Owner

satoren commented Jan 21, 2017

Hi,

I don't get it error. but look like slightly different for C api and kaguya code.

Could you try it with code like the one below?

Match completely code with your C api code.

 kaguya::State luaState;
//load 'add' function to global
auto scriptAdding2CppVariables = R"(
  function add (varA, varB)
    return varA + varB
  end
)";
luaState.dostring(scriptAdding2CppVariables);

//get 'add' function from global
kaguya::LuaFunction luaFunc = luaState["add"];

auto a = 1;
auto b = 2;

if (luaFunc(a, b) == a + b)
{
  std::cout << "SUCCESS" << std::endl;
}
else
{
  std::cout << "FAILED" << std::endl;
}

If you do not want global to dirty.

kaguya::LuaFunction luaFunc = luaState.loadstring("local arg = {...}; return arg[1] + arg[2]");
auto a = 1;
auto b = 2;
assert (luaFunc(a, b) == a + b)

or

//load function returning function.
kaguya::LuaFunction getAddFunc = luaState.loadstring("return function(varA, varB) return varA + varB end");
// get 'add' function
kaguya::LuaFunction luaFunc = getAddFunc ();

// or omitted getAddFunc 
// kaguya::LuaFunction luaFunc = luaState.loadstring("return function(varA, varB) return varA + varB end")();


auto a = 1;
auto b = 2;
assert (luaFunc(a, b) == a + b)

@CaillotKi
Copy link
Author

Hi,

Thanks for this quick answer. I tried your code sample, all three version of it (thanks for the alternatives by the way) and it's still the same.
When using the tool chain -> "attempt to call a nil value", when using my system binary and libraries it's ok.

There must be some incompatibility with some of my toolchain's component I guess but which one ...

@satoren
Copy link
Owner

satoren commented Jan 23, 2017

Hi

What is tool chain?
Could it be that you used different lua_State* or _ENV .

@CaillotKi
Copy link
Author

A toolchain is a set of utilities used for programming. It ensures among other things that your "tools" are compatible with each other.
It allows you to make sure that no matter if the system you're developing on is up to date, no matter if it uses another version of a library than the target you're developing for, the output software will be able to run on the target you're developing for (the ld binary of the toolchain link against the version of the libraries which are available on the final target).

I'm sorry for this "confused" explanation, I'd suggest to check it out on the internet for a better one it is definitely worth to know what it is.

I doubt I'm using a different lua_State with the C api than with Kaguya since both are using the same headers and library (I obviously might have forgotten something so please, feel free to suggest any idea).

As for the _ENV I just quickly googled it but I have to admit I didn't get exactly what it was or what it was used for, let alone how I could be using a different one.

Thanks for your help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants