首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从c内部创建lua表时出错

从c内部创建lua表时出错
EN

Stack Overflow用户
提问于 2014-08-21 14:28:30
回答 1查看 348关注 0票数 1

我有一个A*算法在C,打算使用从Lua。现在,A*本身工作正常,但是由于一些奇怪的原因,当我从Lua调用它时,当任何一个参数函数(Neighbour)创建一个表时,都会出现一个奇怪的错误。用C创建一个表很好。有两个版本的库-第一个称为脚本直接从C在'main‘函数,并创建表从Lua顺利进行。第二种是编译成动态链接库( dll ),并由脚本加载,脚本在创建表时崩溃。为什么,我不知道。我已经尝试过在C中分配我所有的内存,并传递lightuserdata,但是这并没有什么区别。我在同一台机器上编译了其他.dlls,它们不复制此错误。

C库

代码语言:javascript
复制
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脚本

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-08-26 15:18:12

我终于弄明白了:卢阿不喜欢吊坠。当我卸载vc++项目并从我的硬盘上构建它时,一切都很顺利。孩子们,别把卢阿图书馆建在吊坠上。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25428993

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档