开发者

luabind 0.9.1 uses stl iterator only show one element

I got a strange problem while used luabind to return a stl::vector::iterator to lua script.

Below is the code:

1) I created two function they are called by lua script:

std::vector<car*> get_car_list()
{
    std::vector<car*>* vec = new std::vector<car*>();
    vec->push_back(new car("I'm the 1st"));
    vec->push_back(new car("I'm the 2nd")); 
    return *vec;
}

void output(const std::string& msg)
{
    std::cout << "lua:" << msg << std::endl;
}

2) I bind the function to lua

luabind::module(L)
[
    luabind::def("get_car_list", &get_car_list, luabind::return_stl_iterator)
];

luabind::module(L)
[
    luabind::def("output", &output)
];

3) I do the script like below:

function test()
    items  = get_car_list();
    for item in items do
        output(item:get_name开发者_如何学JAVA());
    end
end

4) The result is: In the output window, It only show:

lua:I'm the 1st

And the program is break in the luabind/policy.hpp:754

template <>
struct default_converter<std::string>
  : native_converter_base<std::string>
{
    .....

    void to(lua_State* L, std::string const& value)
    {
        lua_pushlstring(L, value.data(), value.size()); // !!Break Here with Error EXC_BAD_ACCESS
    }
};

I want to display all the elements in the std::vector, but it only show the first one and crash.

Thanks you very much! :)

Jason


I see two problems:

You use pointers and new like if we were in Java but it's C++. You will have clear memory leaks if you use C++ this way.

Except if you have particular reasons, it should be:

std::vector<car> get_car_list() {
    std::vector<car> vec;
    vec->push_back( car("I'm the 1st"));
    vec->push_back( car("I'm the 2nd")); 
    return vec; }

But enters the second problem with your code:

I seems return_stl_iterator assumes that the stl container still exists when you use it and only stores the iterator to this container.

You then can't return a copy of a container the way you do because the container will not exist anymore when you want to use the iterator. It is like if you're using a reference to a temporary container.

As seen in this example luabind doc the idea with return_stl_iterator is to have a container that is still accessible. In the example, the container exists in a struct. It is not a temporary.

You might be tempted to allocate the vector with new and return a reference to this vector in your get_car_list function. But don't do this: when will you free your container then?

If you want to return a vector that does not exist somewhere else ( a temporary copy of a vector), then you should not use the return_stl_iterator policy, it seems not made for this.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜