简体   繁体   English

ObjectiveC Lua:从Lua调用C函数时出错

[英]ObjectiveC Lua: Error in C function call from Lua

I am using two libraries for objectiveC-lua bridge. 我正在为ObjectiveC-lua桥使用两个库。 One is Lua library (with C API) provided by Lua official web page. 一种是Lua官方网页提供的Lua库(带有C API)。 Since that library does not provide API to pass objectiveC object to lua, I opt for another library for this purpose, and Wax seems to be the only option for now. 由于该库未提供将ObjectiveC对象传递给lua的API,因此我为此选择了另一个库,Wax似乎是目前的唯一选择。

This program starts when runLua() is called, where it will invoke test.lua 该程序在调用runLua()时启动,它将在其中调用test.lua

iOS implementation iOS实施

-(void) runLua{
    [self initLua];
    [self invokeLua:@"require test"];
}

-(void)initLua{

   // initialize Lua and our load our lua file
   L = luaL_newstate(); // create a new state structure for the interpreter
   luaL_openlibs(L); // load all the standard libraries into the interpreter

   lua_settop(L, 0);

   initDone = TRUE;
}

-(void) invokeLua:(NSString*)luaSrcStr{
   //NSLog(@"%@",luaSrcStr);

   if(!initDone){
      NSLog(@"inside invokeLua: not yet init");
      [self initLua];
   }

   lua_settop(L, 0);
   int ok = luaL_loadstring(L, [luaSrcStr UTF8String]);
   if(ok == 0){

    lua_getglobal(L,"debug");
    lua_getfield(L,-1, "traceback");
    lua_remove(L,-2);
    lua_insert(L,-2);

    ok = lua_pcall(L, 0, 0, -2);

    if (ok != 0){
        luaL_error(L, "cannot run lua file: %s",
                   lua_tostring(L, -1));

    return;
  }
}

test.lua 测试

local testObject = myLib.newiOSObjWithName("TestObject")
testObject:setObjectLength(3.6)
myLib.passTestObjectToC(testObject) 

There is no problem in executing 1st and 2nd line, only 3rd line, error occurs. 执行第一和第二行没有问题,只有第三行发生错误。

Error 错误

PANIC: unprotected error in call to Lua API (cannot run lua file: attempt to index a nil   
value stack traceback:
[C]: in function 'passTestObjectToC'
...-451C-9F1D-9CE481B4F9A0/test.app/test.lua:6: in main chunk
[C]: in function 'require'
[string "..."]:3: in main chunk)

The error seems to indicate that the function passTestObjectToC is not found in lua, which in this case is not true as the function is registered to lua when luaL_openlibs(L) is called. 该错误似乎表明在lua中找不到函数passTestObjectToC,在这种情况下不正确,因为调用luaL_openlibs(L)时该函数已注册到lua。

My guess, the problem comes where objectiveC object is passed to lua using wax_instance_create(luaState *L, ...). 我的猜测是,问题是使用蜡_实例_创建(luaState * L,...)将ObjectiveC对象传递给lua的。 After passing the object, Wax probably has changed the luaState *L that it doesnt remember that passTestObjectToC is already registered. 传递对象后,Wax可能已更改了luaState * L,它不记得passTestObjectToC已被注册。

The C implementation as below. C的实现如下。

C implementation C实现

static int newiOSObjWithName(lua_State *L){
    NSString *className = [NSString stringWithCString:lua_tostring(L, -1) 
                           encoding:NSUTF8StringEncoding];
    className = [className stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:
                 [[className substringToIndex:1] uppercaseString]];
    id classId = [[NSClassFromString(className) alloc] init];

    luaopen_wax_instance(L);
    wax_instance_create(L, classId, YES);

    return 1;
}

static int passTestObjectToC(lua_State *L){
    // something to be done here

    return 0;
}

static const struct luaL_Reg myLib [] = {
   {"newiOSObjWithName", newiOSObjWithName},
   {"passTestObjectToC", passTestObjectToC},
   {NULL, NULL}
}

int luaopen_mylib (lua_State *L){
   luaL_register(L, "myLib", myLib);
   return 1;
}

linit.c of Lua Library Lua库的linit.c

static const luaL_Reg lualibs[] = {
  {"", luaopen_base},
  {LUA_LOADLIBNAME, luaopen_package},
  {LUA_TABLIBNAME, luaopen_table},
  {LUA_IOLIBNAME, luaopen_io},
  {LUA_OSLIBNAME, luaopen_os},
  {LUA_STRLIBNAME, luaopen_string},
  {LUA_MATHLIBNAME, luaopen_math},
  {LUA_DBLIBNAME, luaopen_debug},
  {"myLib", luaopen_mylib},
  {NULL, NULL}
};


LUALIB_API void luaL_openlibs (lua_State *L) {
  const luaL_Reg *lib = lualibs;
  for (; lib->func; lib++) {
    lua_pushcfunction(L, lib->func);
    lua_pushstring(L, lib->name);
    lua_call(L, 1, 0);
  }
}

Anyone can tell me why there is an error for passTestObjectToC call? 谁能告诉我为什么passTestObjectToC调用出错? What is the reason? 是什么原因?

There is no example of Wax implementation for passing iOSObject available. 没有提供通过iOSObject的Wax实现示例。 I hv not found it. 我找不到。 So I am not sure if this is the right way to do it. 因此,我不确定这是否是正确的方法。 Most examples use Wax to implement iOS classes/functions directly in Lua script instead. 大多数示例使用Wax代替直接在Lua脚本中实现iOS类/功能。

My mistake, there is no problem in the codes above. 我的错误,上面的代码没有问题。 Function passTestObjectToC is successfully called, the error occurred because of the implementation inside passTestObjectToC and not during the calling of passTestObjectToC. 已成功调用函数passTestObjectToC,发生此错误是因为在passTestObjectToC内部实现,而不是在调用passTestObjectToC期间实现。

iOS object is successfully passed from iOS to Lua using Wax as above. 如上所述,使用Wax将iOS对象成功地从iOS传递到Lua。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM