gpt4 book ai didi

c++ - 如何使用 SWIG 为 C++ std::vector 生成 Lua 迭代器?

转载 作者:太空宇宙 更新时间:2023-11-04 14:13:29 25 4
gpt4 key购买 nike

在 SWIG 2.0.8 的 lua/std_vector.i 评论中说:

And no support for iterators & insert/erase

但也许有人知道该怎么做?

例如,可以通过定义__len来添加#length运算符(这可能是偶然的,我是通过反复试验发现的):

%include "std_vector.i"
%extend std::vector { int __len(void*) { return self->size(); } }
namespace std {
%template(PointVector) vector<fityk::Point>;
}

我已经用 __call 尝试过类似的技巧,但我被卡住了。 SWIG 包装妨碍了工作。我试过使用 %native,但我无法让它与 %extend 一起工作。

最佳答案

我不知道如何在 SWIG 模板中执行此操作,但在调用 luaopen_module 之后,我设法将 __call 插入到 SWIG 从 C++ 生成的元表中:

    SWIG_Lua_get_class_metatable(L_, PointVector);
SWIG_Lua_add_function(L_, "__call", lua_vector_iterator);

因此 vector 可以用作迭代器。有点笨拙的 2 合 1,但有效:

> = points
<PointVector userdata: 190FBE8>
> for n, p in points do print(n, p) end
0 (24.0154; 284; 16.8523)
1 (24.0541; 343; 18.5203)

迭代器返回索引和值,就像 Python 中的 enumerate() 一样,Lua 下次将索引传回给迭代器(堆栈中的第 3 个参数)。我还没有看到这种行为的记录,所以我可能依赖于实现细节。

这里是用作__call()的函数:

// SWIG-wrapped vector is indexed from 0. Return (n, vec[n]) starting from n=0.
static int lua_vector_iterator(lua_State* L)
{
assert(lua_isuserdata(L,1)); // in SWIG everything is wrapped as userdata
int idx = lua_isnil(L, -1) ? 0 : lua_tonumber(L, -1) + 1;

// no lua_len() in 5.1, let's call size() directly
lua_getfield(L, 1, "size");
lua_pushvalue(L, 1); // arg: vector as userdata
lua_call(L, 1, 1); // call vector<>::size(this)
int size = lua_tonumber(L, -1);

if (idx >= size) {
lua_settop(L, 0);
return 0;
}

lua_settop(L, 1);
lua_pushnumber(L, idx); // index, to be returned
lua_pushvalue(L, -1); // the same index, to access value
lua_gettable(L, 1); // value, to be returned
lua_remove(L, 1);
return 2;
}

关于c++ - 如何使用 SWIG 为 C++ std::vector 生成 Lua 迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13060314/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com