Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot pass Boost.Any object to C++ Lua binding

https://github.com/Rapptz/sol/ is Sol, a C++11 Lua binding that is freaking awesome.

While I have managed to correctly run code in Sol before, I have been unable to correctly pass a Boost.Any object and unpack it through Lua. With unpack being an alias for boost::any_cast, the code should work. I have defined a new datatype so that Sol and correctly call the copy constructor of the Boost.Any object.

Yet, when I debug the program using GDB, it gives me a SEGFAULT. It appears that Lua fails inside of the copy constructor of Boost.Any.

Do I need to fully define the Boost.Any class? Will Lua call the C++ operators automatically or must I do that myself? Can I pass any operator functions to Lua? Or is it a problem with boost::any_cast?

My theory is that maybe I didn't define the data type far enough for Lua to make full use of Boost.Any.

#include <iostream>
#include <string>
#include <sstream>
#include "lua.hpp"
#include "sol.hpp"

#include "Flexiglass.hpp"

template <class T>
T unpack (boost::any b)
{
    return boost::any_cast<T>(b);
}

int main()
{
    sol::state lua;
    lua.open_libraries(sol::lib::base);

    //This syntax should work here. I did a test case with a templated function.
    lua.set_function<std::string(boost::any)>("unpack", unpack);

    //In order to allow Sol to overload constructors, we do this.
    sol::constructors<sol::types<>,
                    sol::types<boost::any&>,
                    sol::types<boost::any&&>,
                    sol::types<std::string>> constructor;

    //This defines the new class that is exposed to Lua (supposedly)
    sol::userdata<boost::any> userdata("boost_any", constructor);

    //Instantiate an instance of the userdata to register it to Sol.
    lua.set_userdata(userdata);

    //Set boost::any object to a std::string value and pass it to Lua.
    boost::any obj("hello");
    lua.set("b", obj);

    //Contents:
    //print('Hello World!')
    //unpack(b)
    lua.open_file("test.lua");

    //The program outputs "Hello World"
    //But fails at the unpack() method.

    return 0;
}
like image 423
Cinch Avatar asked Mar 03 '26 21:03

Cinch


1 Answers

I've managed to solve this by implementing a similar, yet functioning version of Boost.Any and then implementing a binding by instantiating the function not in the actual set_function, but in the set_function("NAME", function);

This results in a correctly-functioning system in which I can create Any objects in C++ and pass them to Lua, or I can create Any objects in Lua and then pass them to C++. As long as I correctly define how to interface the types back and forth, I am able to unpack and pack data in and out of both C++ and Lua. Together, this creates a great system that allows for easy extension of types that can be exposed to scripting.

I believe I have reached my goal for now, and am interested in any additional thoughts that may come from this.

like image 135
Cinch Avatar answered Mar 05 '26 23:03

Cinch



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!