1

我在使用 luabind 将 stl::vector::iterator 返回到 lua 脚本时遇到了一个奇怪的问题。

下面是代码:

1)我创建了两个由 lua 脚本调用的函数:

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)我将函数绑定到lua

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

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

3)我做的脚本如下:

function test()
    items  = get_car_list();
    for item in items do
        output(item:get_name());
    end
end

4)结果是:在输出窗口中,它只显示:

lua:I'm the 1st

该程序在 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
    }
};

我想显示 std::vector 中的所有元素,但它只显示第一个元素并崩溃。

非常感谢你!:)

杰森

4

1 回答 1

3

我看到两个问题:

您使用指针和 new 就像我们在 Java 中一样,但它是 C++。如果您以这种方式使用 C++,您将有明显的内存泄漏。

除非您有特殊原因,否则应该是:

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; }

但是输入您的代码的第二个问题:

我似乎 return_stl_iterator 假定 stl 容器在您使用时仍然存在,并且仅将迭代器存储到该容器中。

然后,您不能以您的方式返回容器的副本,因为当您想使用迭代器时,该容器将不再存在。就像您使用对临时容器的引用一样。

正如在这个示例luabind doc中看到的,return_stl_iterator 的想法是拥有一个仍然可以访问的容器。在示例中,容器存在于结构中。这不是暂时的。

您可能很想用 new 分配向量并在 get_car_list 函数中返回对该向量的引用。但是不要这样做:那么你什么时候释放你的容器呢?

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.

于 2011-09-13T05:50:23.597 回答