Rapptz / sol

A C++11 Lua wrapper
MIT License
209 stars 32 forks source link

set_function or new_userdata error on Windows/Code::Blocks (newbie question) #48

Closed blackmetal closed 10 years ago

blackmetal commented 10 years ago

Hi, I'm totally new to sol, so maybe my compiling error is stupid. I'm working on Windows 64 bits (compiling in 32 bits) with Code::Blocks 13.12. I recompiled lua 5.2.3 like 10 minutes ago.

This simple code won't compile:

#include <sol.hpp>
#include <cassert>

struct vars {
    int boop = 0;
};

int main() {
    sol::state lua;
    lua.new_userdata<vars>("vars", "boop", &vars::boop);
    lua.script("local beep = vars.new()\n"
               "beep.boop = 1");
    assert(lua.get<vars>("beep").boop == 1);
}

When i use a simple examples (basic.cpp or variables.cpp), the code compile and works as expected but when i use the set_function or new_userdata functions like in the code above, i get the following error:

||=== Build: Debug in lua-test (compiler: GNU GCC Compiler) ===|
C:\...\sol-master\sol\traits.hpp||In instantiation of 'struct sol::detail::check_deducible_signature<void (vars::*)()>':|
...\sol-master\sol\traits.hpp|159|required from 'struct sol::has_deducible_signature<void (vars::*)()>'|
...\sol-master\sol\traits.hpp|239|required from 'struct sol::function_traits<void (vars::*)()>'|
...\sol-master\sol\traits.hpp|252|required from 'struct sol::detail::member_traits<void (vars::*)(), false>'|
...\sol-master\sol\function_types.hpp|37|required from 'struct sol::detail::functor<vars, void (vars::*)(), void>'|
...\sol-master\sol\function_types.hpp|377|required from 'struct sol::userdata_function_core<void (vars::*)(), vars>'|
...\sol-master\sol\function_types.hpp|500|required from 'struct sol::userdata_indexing_function<void (vars::*)(), vars>'|
...\lua\sol-master\sol\userdata.hpp|165|required from 'void sol::userdata<T>::build_function_tables(sol::userdata<T>::function_map_t*&, sol::userdata<T>::function_map_t*&) [with unsigned int N = 0u; T = vars; sol::userdata<T>::function_map_t = std::unordered_map<std::basic_string<char>, std::pair<std::unique_ptr<sol::base_function>, bool> >]'|
...\lua\sol-master\sol\userdata.hpp|301|required from 'void sol::userdata<T>::build_function_tables(sol::userdata<T>::function_map_t*&, sol::userdata<T>::function_map_t*&, std::string, Fx&&, Args&& ...) [with unsigned int N = 0u; Fx = int vars::*; Args = {}; T = vars; sol::userdata<T>::function_map_t = std::unordered_map<std::basic_string<char>, std::pair<std::unique_ptr<sol::base_function>, bool> >; std::string = std::basic_string<char>]'|
...\sol\userdata.hpp|330|required from 'sol::userdata<T>::userdata(std::string, sol::constructors<CArgs ...>, Args&& ...) [with Args = {const char (&)[5], int vars::*}; CArgs = {sol::types<>}; T = vars; std::string = std::basic_string<char>]'|
...\sol-master\sol\state.hpp|169|required from 'sol::state& sol::state::new_userdata(const string&, sol::constructors<CArgs ...>, Args&& ...) [with Class = vars; CArgs = {sol::types<>}; Args = {const char (&)[5], int vars::*}; sol::state = sol::state; std::string = std::basic_string<char>]'|
...\sol-master\sol\state.hpp|164|required from 'sol::state& sol::state::new_userdata(const string&, Args&& ...) [with Class = vars; CTor = {}; Args = {const char (&)[5], int vars::*}; sol::state = sol::state; std::string = std::basic_string<char>]'|
...\lua-test\main.cpp|10|required from here|
...\sol-master\sol\traits.hpp|154|error: invalid use of incomplete type 'struct sol::detail::nat'|
...\sol-master\sol\traits.hpp|152|error: forward declaration of 'struct sol::detail::nat'|
...\sol-master\sol\traits.hpp||In instantiation of 'struct sol::function_traits<void (vars::*)()>':|
...\sol-master\sol\traits.hpp|252|required from 'struct sol::detail::member_traits<void (vars::*)(), false>'|
...\sol-master\sol\function_types.hpp|37|required from 'struct sol::detail::functor<vars, void (vars::*)(), void>'|
...\lua\sol-master\sol\function_types.hpp|377|required from 'struct sol::userdata_function_core<void (vars::*)(), vars>'|
...\lua\sol-master\sol\function_types.hpp|500|required from 'struct sol::userdata_indexing_function<void (vars::*)(), vars>'|
...\lua\sol-master\sol\userdata.hpp|165|required from 'void sol::userdata<T>::build_function_tables(sol::userdata<T>::function_map_t*&, sol::userdata<T>::function_map_t*&) [with unsigned int N = 0u; T = vars; sol::userdata<T>::function_map_t = std::unordered_map<std::basic_string<char>, std::pair<std::unique_ptr<sol::base_function>, bool> >]'|
...\lua\sol-master\sol\userdata.hpp|301|required from 'void sol::userdata<T>::build_function_tables(sol::userdata<T>::function_map_t*&, sol::userdata<T>::function_map_t*&, std::string, Fx&&, Args&& ...) [with unsigned int N = 0u; Fx = int vars::*; Args = {}; T = vars; sol::userdata<T>::function_map_t = std::unordered_map<std::basic_string<char>, std::pair<std::unique_ptr<sol::base_function>, bool> >; std::string = std::basic_string<char>]'|
...\lua\sol-master\sol\userdata.hpp|330|required from 'sol::userdata<T>::userdata(std::string, sol::constructors<CArgs ...>, Args&& ...) [with Args = {const char (&)[5], int vars::*}; CArgs = {sol::types<>}; T = vars; std::string = std::basic_string<char>]'|
...\lua\sol-master\sol\state.hpp|169|required from 'sol::state& sol::state::new_userdata(const string&, sol::constructors<CArgs ...>, Args&& ...) [with Class = vars; CArgs = {sol::types<>}; Args = {const char (&)[5], int vars::*}; sol::state = sol::state; std::string = std::basic_string<char>]'|
...\lua\sol-master\sol\state.hpp|164|required from 'sol::state& sol::state::new_userdata(const string&, Args&& ...) [with Class = vars; CTor = {}; Args = {const char (&)[5], int vars::*}; sol::state = sol::state; std::string = std::basic_string<char>]'|
...\lua-test\main.cpp|10|required from here|
...\sol-master\sol\traits.hpp|239|error: 'value' is not a member of 'sol::has_deducible_signature<void (vars::*)()>'|
...\sol-master\sol\function_types.hpp||In instantiation of 'struct sol::detail::functor<vars, void (vars::*)(), void>':|
...\sol-master\sol\function_types.hpp|377|required from 'struct sol::userdata_function_core<void (vars::*)(), vars>'|
...\sol-master\sol\function_types.hpp|500|required from 'struct sol::userdata_indexing_function<void (vars::*)(), vars>'|
...\sol-master\sol\userdata.hpp|165|required from 'void sol::userdata<T>::build_function_tables(sol::userdata<T>::function_map_t*&, sol::userdata<T>::function_map_t*&) [with unsigned int N = 0u; T = vars; sol::userdata<T>::function_map_t = std::unordered_map<std::basic_string<char>, std::pair<std::unique_ptr<sol::base_function>, bool> >]'|
...\sol-master\sol\userdata.hpp|301|required from 'void sol::userdata<T>::build_function_tables(sol::userdata<T>::function_map_t*&, sol::userdata<T>::function_map_t*&, std::string, Fx&&, Args&& ...) [with unsigned int N = 0u; Fx = int vars::*; Args = {}; T = vars; sol::userdata<T>::function_map_t = std::unordered_map<std::basic_string<char>, std::pair<std::unique_ptr<sol::base_function>, bool> >; std::string = std::basic_string<char>]'|
...\sol-master\sol\userdata.hpp|330|required from 'sol::userdata<T>::userdata(std::string, sol::constructors<CArgs ...>, Args&& ...) [with Args = {const char (&)[5], int vars::*}; CArgs = {sol::types<>}; T = vars; std::string = std::basic_string<char>]'|
...\sol-master\sol\state.hpp|169|required from 'sol::state& sol::state::new_userdata(const string&, sol::constructors<CArgs ...>, Args&& ...) [with Class = vars; CArgs = {sol::types<>}; Args = {const char (&)[5], int vars::*}; sol::state = sol::state; std::string = std::basic_string<char>]'|
...\sol-master\sol\state.hpp|164|required from 'sol::state& sol::state::new_userdata(const string&, Args&& ...) [with Class = vars; CTor = {}; Args = {const char (&)[5], int vars::*}; sol::state = sol::state; std::string = std::basic_string<char>]'|
...\lua-test\main.cpp|10|required from here|
...\sol-master\sol\function_types.hpp|37|error: no type named 'args_type' in 'struct sol::detail::member_traits<void (vars::*)(), false>'|
...\sol-master\sol\function_types.hpp|38|error: no type named 'return_type' in 'struct sol::detail::member_traits<void (vars::*)(), false>'|
...\sol-master\sol\function_types.hpp|59|error: no type named 'return_type' in 'struct sol::detail::member_traits<void (vars::*)(), false>'|
...\sol-master\sol\function_types.hpp||In member function 'int sol::userdata_indexing_function<Function, Tp>::fx_call(lua_State*) [with Tx = vars*; Function = void (vars::*)(); Tp = vars; lua_State = lua_State]':|
...\sol-master\sol\function_types.hpp|540|warning: control reaches end of non-void function [-Wreturn-type]|
...\sol-master\sol\function_types.hpp||In member function 'int sol::userdata_indexing_function<Function, Tp>::fx_call(lua_State*) [with Tx = vars; Function = void (vars::*)(); Tp = vars; lua_State = lua_State]':|
...\sol-master\sol\function_types.hpp|540|warning: control reaches end of non-void function [-Wreturn-type]|
||=== Build failed: 6 error(s), 35 warning(s) (0 minute(s), 0 second(s)) ===|

Can someone tell me what i did wrong? Thanks a lot in advance :)

Rapptz commented 10 years ago

Thanks for the report. Unfortunately I can't reproduce.

What compiler version are you using?

ThePhD commented 10 years ago

Just a guess, but CodeBlocks recommends GCC 4.7.1 with its default CodeBlocks 13.12 installer.

If that's the case, you might need to explicitly pass the -std=c++11 to CodeBlock's compiler settings to make sure it's properly able to handle some of the later features.

I would also recommend downloading and using the codeblocks-13.12mingw-setup-TDM-GCC-481.exe version, since GCC 4.8.1 is the latest and greatest and starting out on an older version doesn't help you at all.

blackmetal commented 10 years ago

I'm currently using the gcc 4.7.1 version. In CodeBlocks, you can add this flag directly in the options (and i added it that way), i'll try to add it manually. I'll try to install a newer version of gcc and see how it goes with it. Thanks for the replies.

blackmetal commented 10 years ago

Ok, so now i'm in gcc 4.8.1 version, i get a segfault when i run the same script i posted above (it compiles, first victory!) The segfault is on that line:

assert(lua.get<vars>("beep").boop = 1);

It's not the assert that makes the error (i tried to remove the assert and stored the lua.get("beep") in a variable. When i tried to print &my_var the program crashed.)

Rapptz commented 10 years ago

Okay. Now I can reproduce. Apparently, I forgot I was building with 'Release' last time. The build is definitely failing on my end.

Rapptz commented 10 years ago

This is also a possible duplicate of #25 and #35 which have their own test case and pass them just fine.

ThePhD commented 10 years ago

Turns out this is a clerical error: the front page/examples should be fixed and this should be registered as not-a-bug.

int main() {
    sol::state lua;
    lua.new_userdata<vars>("vars", "boop", &vars::boop);
    lua.script("local beep = vars.new()\n"
               "beep.boop = 1");
    assert(lua.get<vars>("beep").boop == 1);
}

Notice in the snippet that there is local beep = ..., then the rest of the code.

local means that variable is inaccessible outside of its scope. It's not stored in the global lua table once the script is done running: it's made inaccessible and marked for garbage collection.

So it's actually behaving as it should be. Remove the local and it'll do what you want.

[ Extra Nitpicky Notes ] As a final warning, make sure you get the value with auto& if you care about not making a copy, as auto just resolves to vars and if you do vars my_vars = lua.get<vars>("beep");, whatever you have will be a copy from lua, not a reference to the actual data.

blackmetal commented 10 years ago

Ok :) Thanks for the answer.