【发布时间】:2017-03-01 06:41:02
【问题描述】:
我正在 C 中实现一个泛型 for 迭代器函数。返回泛型 for 循环的迭代器函数的函数首先使用 lua_newuserdata() 为迭代器函数分配状态信息,如下所示:
struct mystate *s = (struct mystate *) lua_newuserdata(L, sizeof(struct mystate));
s->firstcall = 1;
然后我将指针作为上值推送到我的 C 闭包中,如下所示:
lua_pushvalue(L, lua_gettop(L));
lua_pushcclosure(L, iteratorfunction, 1);
然后我的迭代器函数从第一个上值中检索指针并对其进行一些分配,如下所示:
static int iteratorfunction(lua_State *L)
{
struct mystate *s = (struct mystate *) lua_touserdata(L, lua_upvalueindex(1));
if(s->firstcall) {
s->file = fopen(...);
s->data = malloc(...);
...
s->firstcall = 0;
}
...
}
现在我的问题是:如果脚本在完成之前使用break 退出通用for 循环,我应该如何确保s->file 和s->data 被正确释放?在这种情况下,我的iteratorfunction 无法进行清理,因为它并没有一直被调用。相反,通用 for 循环在我的迭代器函数完成之前退出。
确切地说,如果脚本使用break 在完成之前退出我的通用for循环,我如何确保在s->file 上调用fclose() 和在s->data 上调用free()?
我查看了 Lua 源代码,io.lines 似乎使用元表和垃圾收集器来确保文件句柄已关闭,但我真的不明白它是如何工作的。它看起来很复杂,我不确定是否应该以类似的方式执行此操作,或者是否有更简单的解决方案适合我的情况。
请注意,我仍在使用 Lua 5.0,因此对于解决方案的任何建议都应牢记这一点。谢谢!
【问题讨论】:
-
恐怕除了使用终结器之外没有其他解决方案(
__gcmetamethod) -
谢谢,我刚刚根据您的建议发布了完整的答案。