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.
精彩评论