我正在开发一个可以运行Lua脚本的iOS应用,我可以轻松地将lua基本支持与CocoaPods集成在一起,但是如何向其中添加LuaSocket库呢? LuaSocket包含一些C和一些Lua文件,有人有想法吗?谢谢!

最佳答案

在iOS 8允许使用动态框架(库)的情况下,可能会有更优雅的方法,但是以下方法可用于Lua 5.2.3(因为您正在使用Cocoapods,而5.2.3是Cocoapod提供的版本)和LuaSocket 3.0-rc1

注意,我实际上不使用Cocoapod;在您的iOS项目中包含Lua非常简单,我觉得使用Cocoapods不值得。 YMMV。由于路径差异,您可能需要对我在下面描述的内容进行一些调整。

  • 创建一个新的iOS'Single View'项目
  • 在XCode的项目导航器
  • 中创建一个名为Lua的组。
  • 将Lua下载中src目录中的所有文件(lua.c,luac.c,lua.hpp和makefile除外)复制到该组
  • 在XCode的项目导航器
  • 中创建一个名为LuaSocket的组
  • 将LuaSockets下载中src目录中的所有文件(makefile,wsocket.c和wsocket.h除外)复制到该组
  • 将LutSocket源代码
  • 中的#import "luasocket.h"行添加到文件serial.h中

    此时,您应该能够构建并运行该应用程序,而不会出现任何错误。当然,它实际上还没有做任何事情...

    首先,我们将修改luaL_openlibs,使其按以下方式初始化LuaSocket的C代码。

    在Lua源代码中,找到文件linit.c并进行更改
    static const luaL_Reg loadedlibs[] = {
      {"_G", luaopen_base},
      {LUA_LOADLIBNAME, luaopen_package},
      {LUA_COLIBNAME, luaopen_coroutine},
      {LUA_TABLIBNAME, luaopen_table},
      {LUA_IOLIBNAME, luaopen_io},
      {LUA_OSLIBNAME, luaopen_os},
      {LUA_STRLIBNAME, luaopen_string},
      {LUA_BITLIBNAME, luaopen_bit32},
      {LUA_MATHLIBNAME, luaopen_math},
      {LUA_DBLIBNAME, luaopen_debug},
      {NULL, NULL}
    };
    


      {"_G", luaopen_base},
      {LUA_LOADLIBNAME, luaopen_package},
      {LUA_COLIBNAME, luaopen_coroutine},
      {LUA_TABLIBNAME, luaopen_table},
      {LUA_IOLIBNAME, luaopen_io},
      {LUA_OSLIBNAME, luaopen_os},
      {LUA_STRLIBNAME, luaopen_string},
      {LUA_BITLIBNAME, luaopen_bit32},
      {LUA_MATHLIBNAME, luaopen_math},
      {LUA_DBLIBNAME, luaopen_debug},
      {"socket", luaopen_socket_core},
      {"mime", luaopen_mime_core},
      {NULL, NULL}
    };
    

    您需要在linit.c的顶部添加#include "luasocket.h"#include "mime.h"

    您还需要将几个其他C函数添加到此列表中,例如luaopen_socket_unix,但我将保留它们作为读者的练习。

    现在,我们转到LuaSocket中包含的各种Lua源文件,例如socket.lua和mime.lua。与其使用require来加载它们,不如使用luaL_dofile来执行它们。

    为了具体,假设我们要使用LuaSocket对我们的视图控制器进行一些初始化。我们将在viewDidLoad中创建Lua状态,称为luaL_openlibs,以初始化核心库和LuaSocket的C库,然后将使用NSBundle中的例程获取要运行的Lua文件的文件路径。

    我们需要编辑Lua文件以删除require socket.core,mime.core等的任何行,因为这比尝试使require正常运行更为简单。此外,socket.core和mime.core已经通过我们修改的luaL_openlibs进行了初始化,因此无需对其进行require

    所以viewDidLoad看起来像这样:
    - (void)viewDidLoad
    {
      [super viewDidLoad];
    
      lua_State *L = luaL_newstate();
      luaL_openlibs(L);
    
      // Load socket.lua and mime.lua
    
      NSString *fp = [[NSBundle mainBundle] pathForResource:@"socket" ofType:@"lua"];
      luaL_dofile(L, [fp cStringUsingEncoding:NSUTF8StringEncoding]);
    
      fp = [[NSBundle mainBundle] pathForResource:@"mime" ofType:@"lua"];
      luaL_dofile(L, [fp cStringUsingEncoding:NSUTF8StringEncoding]);
    
      lua_settop(L, 0); // ignore return values from the calls to dofile
    
    
      // Now do something with the Lua state and LuaSockets
    
      NSString *script = @"res = mime.b64('LuaSocket', 'works')";
      luaL_dostring(L, [script cStringUsingEncoding:NSUTF8StringEncoding]);
      lua_getglobal(L, "res");
      const char *s  = luaL_checkstring(L, 1);
      NSLog(@"res = %@", [NSString stringWithCString:s encoding:NSUTF8StringEncoding]);
    }
    

    仍然有一些松散的结局,但这应该说明要点。您可以查看我在Github上创建的example project。在接下来的几天里,我将对其进行清理,并演示更多LuaSocket的功能。

    10-05 19:17