简体   繁体   中英

ObjectiveC Lua: Error in C function call from Lua

I am using two libraries for objectiveC-lua bridge. One is Lua library (with C API) provided by Lua official web page. 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.

This program starts when runLua() is called, where it will invoke test.lua

iOS implementation

-(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.

My guess, the problem comes where objectiveC object is passed to lua using wax_instance_create(luaState *L, ...). After passing the object, Wax probably has changed the luaState *L that it doesnt remember that passTestObjectToC is already registered.

The C implementation as below.

C implementation

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

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? What is the reason?

There is no example of Wax implementation for passing iOSObject available. 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.

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.

iOS object is successfully passed from iOS to Lua using Wax as above.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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