我在C中有一个A *算法,打算从Lua中使用。现在,A *本身工作正常但是出于一些奇怪的原因,当我从Lua调用它时,当任何一个参数函数(邻居)创建一个表时,会弹出一个奇怪的错误。在C中创建表工作正常。 这个库有两个版本 - 第一个版本直接从C中的主要版本中调用脚本'功能,并从Lua创建表格顺利。第二个编译为dll并由脚本加载,在创建表时崩溃。为什么,我不知道。 我已经尝试在C中分配所有内存并传递lightuserdata,但它没有任何区别。 我在同一台机器上编译了其他.dll,并没有复制此错误。
C LIBRARY
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 SCRIPT
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
答案 0 :(得分:0)
我终于明白了:Lua不喜欢pendrives。 当我卸载vc ++项目并从我的硬盘驱动器构建它时,一切都正常。 孩子们,不要在pendrive上建立Lua库。