gpt4 book ai didi

c - 从 c api 内部创建 lua 表时出错

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

我在 C 中有一个 A* 算法,打算在 Lua 中使用。现在,A* 本身工作正常,但由于某些奇怪的原因,当我从 Lua 调用它时,当任何一个参数函数(邻居)创建表时,会弹出一个奇怪的错误。在 C 中创建表工作正常。该库有 2 个版本——第一个版本在“main”函数中直接从 C 调用脚本,从 Lua 创建表工作顺利。第二个被编译为 dll 并由在制作表格时崩溃的脚本加载。为什么,我不知道。我已经尝试在 C 中分配我所有的内存并传递 lightuserdata 但它没有任何区别。我在同一台机器上编译了其他 .dll,它们不会复制此错误。

C 库

int run(lua_State *L)
/*
1: string from,
2: string to,
3: string[] Neighbours(string of),
4: int Cost(string from, string to, string dest),
5: int Heuristic(string from, string to, string dest)
*/
{
char flag = 0;
HE = HE ? HE : Heap_Alloc(200);
Heap_Clear(HE);

// create the HASHtable
lua_createtable(L,1,300);
// 6 - HASHtable (string -> {int cost,string Self,string parent})


// get Heuristic(0,from,to)
lua_pushvalue(L,5);
lua_pushstring(L,0);
lua_pushvalue(L,1);
lua_pushvalue(L,2);
lua_call(L,3,1);

{
// 7 - Heuristic(0,from,to)
Heap_val_t hp = {lua_tointeger(L,7), lua_tostring(L,1)};
Z q;

// HASH[from] = {cost=Heuristic, self=from, parent=nil}
lua_pushvalue(L,1);
lua_newuserdata(L,sizeof(struct g));
q = lua_touserdata(L,-1);
q->_cost = lua_tointeger(L,7);
q->_self = lua_tostring(L,1);
q->_parent = 0;
lua_rawset(L,6);

// pop Heuristic(0,from,to) (6)
lua_pop(L,1);

Heap_Push_macro(HE, hp);


while (!Heap_Empty(HE))
{
int i=1;
hp = Heap_Top(HE);
Heap_Pop_macro(HE);

// push Neighbours(Self) on the stack
lua_pushvalue(L,3);
lua_pushstring(L,hp._self);
lua_call(L,1,1); // ALLOCATING TABLE INSIDE THIS GENERATES THE ERROR


while(1)
{
// 7 - neighbours table[]

// push neighbours[i]
lua_rawgeti(L,-1,i);

// check if we got to the end of neighbours
if (!lua_isstring(L,-1))
{
lua_pop(L,1);
break;
}
{
// 8 - neighbours[i]
int cost,heur;

// get HASH[hp.self].cost and pop from stack
lua_pushstring(L,hp._self);
lua_rawget(L,6);
q = lua_touserdata(L,-1);
cost = q->_cost;
lua_pop(L,1);

// call Cost(hp.self,*neighbours,to)
lua_pushvalue(L,4);
lua_pushstring(L,hp._self);
lua_pushvalue(L,8);
lua_pushvalue(L,2);
lua_call(L,3,1);
// add it to cost and remove from stack
cost += lua_tointeger(L,-1);
lua_pop(L,1);

// get Heuristic(hp._obj, *neighbours, to) and pop it
lua_pushvalue(L,5);
lua_pushstring(L,hp._self);
lua_pushvalue(L,8);
lua_pushvalue(L,2);
lua_call(L,3,1);
heur = lua_tointeger(L,-1);
lua_pop(L,1);

// get HASH[*neighbours]
lua_pushvalue(L,8);
lua_rawget(L,6);
q = lua_touserdata(L,-1);

if (!q || q->_cost > cost+heur)
{
Heap_val_t y = {cost+heur, lua_tostring(L,8)};
Heap_Push_macro(HE, y);
// HASH[*neighbours] = {cost=cost, self=*neighbours, parent=hp.self}
lua_pushvalue(L,8);
lua_newuserdata(L,sizeof(struct g));
q = lua_touserdata(L,-1);
q->_cost = cost;
q->_self = lua_tostring(L,8);
q->_parent = hp._self;
lua_rawset(L,6);
}
// remove 10
lua_pop(L,1);
// 9

}
// remove neighbours[i]
lua_pop(L,1);
i++;
// 8
}


// remove neighbours[]
lua_pop(L,1);
// 7

lua_pushstring(L,hp._self);
if (lua_equal(L,-1,2))
{
flag = 1;
// pop the string
lua_pop(L,1);
break;
}
lua_pop(L,1);
}


// 7 - return path table
lua_createtable(L,1,1);
if (flag)
{
int i=1,j;

while(1)
{
Z g;
lua_pushvalue(L,2);
lua_rawget(L,6);
g = lua_touserdata(L,-1);
if (!g->_parent)
{
lua_pop(L,1);
break;
}

lua_pushstring(L,g->_parent);
lua_replace(L,2);
lua_pushstring(L,g->_self);
lua_rawseti(L,7,i++);
lua_pop(L,1);
}

// reverse the table
for (j=1, i--; i-j > 0; i--,j++)
{
lua_rawgeti(L,7,j);
lua_rawgeti(L,7,i);
lua_rawseti(L,7,j);
lua_rawseti(L,7,i);
}
}
}

// replace HASH with return table
lua_replace(L,6);
return 1;
}

LUA 脚本

require 'astar'

function X(z)
local a = z:find'[? ]'
return tonumber(z:sub(1,a))
end
function Y(z)
local a = z:find'[? ]'
return tonumber(z:sub(a))
end


m,n = {-1,-1,-1,0,0,1,1,1},{-1,0,1,-1,1,-1,0,1}
function neighbours(of)
print('neighbours',of)
local x,y = X(of),Y(of)
-- local r = {} -- creating a table from inside the C api crashes
local r = 0

for i=1,#m do
local nx,ny = x+m[i],y+n[i]
--table.insert(r,nx..' '..ny)
end

return r
end

function cost(from,to,dest)
return 1
end
function heuristic(from,to,dest)
local x1,y1,x2,y2 = X(to),Y(to),X(dest),Y(dest)
return math.abs(x1-x2)+math.abs(y1-y2)
end


print{} -- making tables before C api call..
r = astar.run('0 0','1 0', neighbours, cost, heuristic)
print{} -- ..or after doesn't crash

print('r',r)
if r then
print(#r)
for i,j in pairs(r) do
print(i,j)
end
end

最佳答案

我终于明白了:Lua 不喜欢 pendrives。当我卸载 vc++ 项目并从我的硬盘构建它时,一切正常。 children ,不要在 pendrive 上构建 Lua 库。

关于c - 从 c api 内部创建 lua 表时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25428993/

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