将Lua嵌入IOS程序

转自:http://blog.youkuaiyun.com/wildfireli/article/details/19057809

Lua的目标是成为一个很容易嵌入其它语言中使用的语言。很多应用程序使用LUA作为自己的嵌入式脚本语言,以此来实现可配置性、可扩展性,以便程序更灵活和更好的扩展。
一、在Xcode中配置Lua
http://www.lua.org 下载Lua ,解压缩 打开你要添加使用lua的项目工程,选择点击左侧工程管理文件,点击右边资源栏下方Add Target,选择添加一个 static Libarary 工程.取名叫lua

将Lua嵌入IOS程序 - Tolecen - Tolecens Blog

将解压后的lua src文件 拖动到工程新生成的lua 文件夹下

将Lua嵌入IOS程序 - Tolecen - Tolecens Blog

去掉Create external build前面的勾

将Lua嵌入IOS程序 - Tolecen - Tolecens Blog

next 后选择targets里的 lua

将Lua嵌入IOS程序 - Tolecen - Tolecens Blog

编译静态库 lua 项目,这样就会生成一个libLua.a的静态库
选择原本项目工程 target 加入lua 静态库

将Lua嵌入IOS程序 - Tolecen - Tolecens Blog

现在Lua就成功的配置到Xcode中了。

二、使用Lua
使用Lua,首先要在本地新建Lua文件。比如要在iPhone中使用,可以将文件建立在App下的Documents文件夹下,或者可以放在服务器端,使用时下载下来。
比如此处我新建了两个Lua文件,一个叫Engine.lua,用来驱动真正的lua执行方法的文件,另一个叫todo.lua,用来实现你要让IOS程序执行的方法。
要调用lua,首先你可以像正常那样建立一个ViewController,在ViewController里写调用Engine.lua的方法,将这个方法放在ViewController的一个线程里执行。

ViewController的代码:

//  ViewController.m
//  wwwwww
//
//  Created by Tolecen 12-11-19.
//  Copyright (c) 2012年 Tolecen . All rights reserved.

//

#import "ViewController.h"
#include "lua.hpp"
extern "C"
{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
#define NOERROR 0
#define LUA_PMCNT_CHECK(n)\
{ \
int nParamCnt = lua_gettop(L) ; \
if( nParamCnt != n ) \
    {\
        lua_pushnumber( L , -1 ) ; \
        return 1 ; \
    } \
}

#define LUA_RET_VALUE(n)\
{ \
    lua_pushnumber( L , n );  \
return 1 ; \
}

#define LUA_OUT_ERROR(id) lua_pushnumber(L, id);if (id != 0) return 1;

int logYouWhat(lua_State *L)  //你想要让Lua执行的方法,需用C++写
{
    LUA_PMCNT_CHECK(2);
    int aa = (int)lua_tonumber(L, 1);
    int bb = (int)lua_tonumber(L, 2);
    NSLog(@"aa:%d,bb:%d",aa,bb);
    [ViewController changeA:aa B:bb]; //在此c++方法里通过这个ViewController的类方法调用OC方法,以实现设置UI等操作
    return 0;
}


unsigned long luaWork(void* pParam) //此方法用来调用Engine.lua,以驱动Lua语句
{
    int i;
    int j;
    int s0;
    int s1;
    int nResult;
    lua_State *L;
    int nThreadIndex;
    lua_State *lLocal;
    char strPathName[512];
    char strLuaEngine[512];
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    memset(strPathName, 0, 512);
    const char * tmp=  [documentsDirectory UTF8String];
    strncpy(strPathName, (char*)tmp, strlen(tmp)); //这是查找本地App的Documents语句,以便将lua文件加到此处   
    L = luaL_newstate();
    if (L == NULL)
    {
         NSLog(@"error: %s \n" , lua_tostring(L, -1)); //lua程序执行有错误,此处会打印lua的错误行数,下同
         return -1;
    }
    luaL_openlibs(L);
    j = 0;
    for (i = 0;i < 260;i++)
    {
        if (strPathName[i] == 0)
            break;       
        if (strPathName[i] == '\\')
        j = i;
     }    
    if (j != 0)
    strPathName[j] = 0;
    NSString *logPath = [documentsDirectory stringByAppendingPathComponent:@"Engine.lua"];
    const char * tmp1=  [logPath UTF8String];
    strncpy(strLuaEngine, (char*)tmp1, strlen(tmp1));
    NSLog(@"strLuaEngine %s \n",strLuaEngine);
    s1 = luaL_loadfile(L, strLuaEngine); //通过Engine.lua的路径load lua文件,实现要将Engine.lua和todo.lua存入目录
    if (s1 != 0)
    {          
        NSLog(@"error: %s \n" , lua_tostring(L, -1));
        lua_pop(L, 1);
        return -10;
    }   
    s1 = lua_pcall(L, 0, 0, 0);
    if (s1 != 0)
    {
        NSLog(@"error: %s \n" , lua_tostring(L, -1));
        getchar();
        lua_pop(L, 1);
        return -11;
    }
    lua_register(L, "logSomething", logYouWhat);//将这个Viewcontroller中的方法在Lua中注册,中间那个就是要在lua里执行的方     法名
    lua_getglobal(L, "ywyengine");    
    if (!lua_istable(L, -1))
    {
        NSLog(@"error: %s \n" , lua_tostring(L, -1));
        lua_pop(L, 1);
        return -3;
    }   
    lua_pushstring(L, "CreateSession");
    lua_gettable(L, -2);   
    if (!lua_isfunction(L, -1))
    {
        NSLog(@"error: %s \n" , lua_tostring(L, -1));
        lua_pop(L, 2);
        return -4;
    }    
    s0  = lua_pcall(L, 0, 2, 0);
    if (s0 != 0)
    {
        NSLog(@"error: %s \n" , lua_tostring(L, -1));
        lua_pop( L, 1 );
        return -5;
    }   
    lLocal = lua_tothread(L, -2);
    nThreadIndex = lua_tonumber(L, -1);    
    lua_pop(L, 2);    
    while(1)
    {
        NSLog(@"run");
        lua_getglobal(L, "ywyengine");        
        if (!lua_istable(L, -1))
        {
             NSLog(@"error: %s \n" , lua_tostring(L, -1));
            lua_pop(L, 1);
            return -6;
        }       
        lua_pushstring(L, "ContinueSession");
        lua_gettable(L, -2);
        if (!lua_isfunction(L, -1))
        {
            NSLog(@"error: %s \n" , lua_tostring(L, -1));
            lua_pop(L, 2);
            return -7;
        }       
        lua_pushnumber(L, nThreadIndex);       
        s0  = lua_pcall(L, 1, 1, 0);
        if (s0 != 0)
        {

            NSLog(@"error: %s \n" , lua_tostring(L, -1));
            lua_pop( L, 1 );
            return -8;
        }       
        nResult = lua_tonumber(L, -1);
        lua_pop(L, 1);       
        if (nResult)
        return -9;
    }    
    return 0;
}

@interface ViewController ()

@end


@implementation ViewController

- (void)viewDidLoad

{

    [super viewDidLoad];   

    dispatch_queue_t queue = dispatch_queue_create("com.example.dothis", NULL);

    dispatch_async(queue, ^{

        luaWork(NULL);

    });

// Do any additional setup after loading the view, typically from a nib.

}


+(void)changeA:(int)as B:(int)bs

{

    NSLog(@"hahaTHEA:%d",as);

}

Engine.lua的代码

require("/var/mobile/Applications/4FDA7C3C-984F-43C9-A306-6C95C758AF78/Documents/todo")

--上面是将todo.lua的路径交代给Engine.lua,以便调用todo.lua里的方法,每一个程序的路径不一样,要改成自己程序的路径

threadhandle = {}

handlecount = 0

ywyengine = {}


function ywyengine.Susport(  )

coroutine.yield()

end


function ywyengine.ContinueSession( handleindex )

local status, err, result


if (type(threadhandle[handleindex]) ~= "thread") then

print( "ContinueSession error no thread" ) 

result = 1

return result

end

if (threadhandle[handleindex] == nil) then

print( "ContinueSession error thread nil" ) 

result = 2

return result

end


if (coroutine.status( threadhandle[handleindex] ) == "dead") then

result = 3

print( "ContinueSession error thread dead" ) 

threadhandle[handleindex] = nil

return result

end

status , err = coroutine.resume( threadhandle[handleindex] , 0 )


  if status == false then

  result = 4

  print( "ContinueSession error" ) 

  print(err)

  else

    result = 0

end 

print( "ContinueSession ok" ) 

return result

end


function ywyengine.CreateSession()

    local handle = coroutine.create( StartSession )

    local status, err

    local sessioninfo = {}

    local coroutine_info = {

        param   = sessioninfo ,  

      }



    handlecount = handlecount + 1

    threadhandle[handlecount] = handle    

    status, err = coroutine.resume( threadhandle[handlecount] , coroutine_info )  

    if status == false then

         print( "CreateSession error" ) 

    print(err)

    end



    print("Start session ok")

  return handle, handlecount

end

以下为todo.lua的代码


function StartSession(args)


while true do

       logSomething(45,78);//这就是viewcontroll中注册的那个方法,对应的c++方法在上方已写

       print("Continue ok");

       ywyengine.Susport();

end

end

lua在Xcode的配置参照博客 http://www.cnblogs.com/hurricane2011/articles/2252368.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值