【问题标题】:Why does LuaJIT produce a "too many callbacks error" from this simple code?为什么 LuaJIT 会从这个简单的代码中产生“太多回调错误”?
【发布时间】:2015-09-11 14:21:51
【问题描述】:

我正在使用 LuaJIT 并在此代码中遇到“回调太多”异常。我知道可以生成的 c 回调的数量是有限制的,但据我所知,这应该只生成一个回调......对吗?

ffi = require('ffi')
ffi.cdef([[typedef double cpFloat;
typedef struct cpSpace cpSpace;
typedef struct cpBody cpBody;

cpSpace* cpSpaceNew(void);
cpBody* cpBodyNew(cpFloat mass, cpFloat moment);
cpBody* cpSpaceAddBody(cpSpace *space, cpBody *body);

typedef void (*cpSpaceBodyIteratorFunc)(cpBody *body, void *data);
void cpSpaceEachBody(cpSpace *space, cpSpaceBodyIteratorFunc func, void *data);

]])

chipmunk = ffi.load("chipmunk")
space = chipmunk.cpSpaceNew()
body = chipmunk.cpBodyNew(10, 100)
chipmunk.cpSpaceAddBody(space, body)

drawBody = function(body, x) end
CALL_COUNT = 5000
for i = 1, CALL_COUNT do
  chipmunk.cpSpaceEachBody(space, drawBody, nil)
end

如果 CALL_COUNT 减少到 500,它可以正常工作。

异常如下:

Error: main.lua:25: too many callbacks
stack traceback:
    [C]: in function 'cpSpaceEachBody'
    mainmoon.lua:25: in main chunk
    [C]: in function 'require'
    main.lua:1: in main chunk
    [C]: in function 'require'
    [string "boot.lua"]:374: in function <[string "boot.lua"]:244>
    [C]: in function 'xpcall'

上下文:我正在将 Chipmunk 与 Mac OS X 上的 Love2D 平台集成。

【问题讨论】:

    标签: lua chipmunk love2d luajit


    【解决方案1】:

    在 LuaJIT 中,C 回调是有限资源。见http://luajit.org/ext_ffi_semantics.html#callback

    您的函数cpSpaceEachBody 将函数作为第二个参数。 每次调用它;您正在创建一个新的 C 函数。

    除了创建太多;你永远不会释放他们。

    您应该尽可能少地使用 C 函数。在您的示例中,您每次都使用相同的功能,所以这是一个简单的修复:

    ffi = require('ffi')
    ffi.cdef([[typedef double cpFloat;
    typedef struct cpSpace cpSpace;
    typedef struct cpBody cpBody;
    
    cpSpace* cpSpaceNew(void);
    cpBody* cpBodyNew(cpFloat mass, cpFloat moment);
    cpBody* cpSpaceAddBody(cpSpace *space, cpBody *body);
    
    typedef void (*cpSpaceBodyIteratorFunc)(cpBody *body, void *data);
    void cpSpaceEachBody(cpSpace *space, cpSpaceBodyIteratorFunc func, void *data);
    
    ]])
    
    chipmunk = ffi.load("chipmunk")
    space = chipmunk.cpSpaceNew()
    body = chipmunk.cpBodyNew(10, 100)
    chipmunk.cpSpaceAddBody(space, body)
    
    drawBody = function(body, x) end
    drawBody_C_func = ffi.cast("cpSpaceBodyIteratorFunc", drawBody)
    CALL_COUNT = 5000
    for i = 1, CALL_COUNT do
      chipmunk.cpSpaceEachBody(space, drawBody_C_func, nil)
    end
    drawBody_C_func:free()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-19
      • 2016-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多