繁体   English   中英

如何在iOS应用中使用LuaSocket?

[英]How can I use LuaSocket in iOS app?

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

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

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

  1. 创建一个新的iOS'Single View'项目
  2. 在XCode的项目导航器中创建一个名为Lua的组
  3. 将Lua下载中src目录中的所有文件(lua.c,luac.c,lua.hpp和makefile除外)复制到该组中
  4. 在XCode的项目导航器中创建一个名为LuaSocket的组
  5. 将LuaSockets下载中src目录中的所有文件(makefile,wsocket.c和wsocket.h除外)复制到该组中
  6. 在LuaSocket源代码中的文件serial.h中添加行#import "luasocket.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}
};

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

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

现在,我们转到LuaSocket中包含的各种Lua源文件,例如socket.lua和mime.lua。 与其使用require来加载它们, luaL_dofile使用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上创建的示例项目 在接下来的几天里,我将对其进行清理,并演示更多LuaSocket的功能。

我使用LuaSocket的2.0.2版本和Lua的5.1版本。 修改一些文件后[未知类型名称'luaL_reg'; 你是说'luaL_Reg'吗? ]我能够编译。 还删除了wsocket(.h&.c)文件。 因此正在编译。 经过一番搜索,我发现Cocos2d-x源代码(3.0.4)也使用luasocket文件夹(并具有liblua.a)。 再次删除了wsocket文件,然后编译没有错误。 我用了

    -(void)addBundlePathToLuaState:(lua_State*)L
   {
    lua_getglobal(L, "package");
   lua_getfield(L, -1, "path"); // get field "path" from table at top of stack (-1)

   const char* current_path_const = lua_tostring(L, -1); // grab path string from top of stack
   NSString* current_path = [NSString stringWithFormat:@"%s;%@/?.lua", current_path_const, [[NSBundle mainBundle]resourcePath]];

   lua_pop(L, 1); // get rid of the string on the stack we just pushed on line 5
   lua_pushstring(L, [current_path UTF8String]); // push the new one
   NSLog(@"path current %s", [current_path UTF8String]);
   lua_setfield(L, -2, "path"); // set the field "path" in table at -2 with value at top of stack
   lua_pop(L, 1); // get rid of package table from top of stack
     }

   int status;
   lua_State *La;
   La = luaL_newstate();
   NSBundle* myBundle = [NSBundle mainBundle];
   NSString* myImage = [myBundle pathForResource:@"a" ofType:@"lua"];
   const char *stringAsChar = [myImage cStringUsingEncoding:[NSString defaultCStringEncoding]];
   NSLog(@"mypath %s", stringAsChar);
   luaL_openlibs(La); /* Load Lua libraries */
/* Load the file containing the script we are going to run */
   status = luaL_loadfile(La, stringAsChar);
   NSString *luaFilePath = [[NSBundle mainBundle] pathForResource:@"a" ofType:@"lua"];
   [self addBundlePathToLuaState:La];

我的脚本使用本地套接字= require(“ socket”),但问题是它找不到核心socket.lua:13:找不到模块'socket.core':无字段package.preload ['socket.core']

所以我认为您不会很快获得成功:)

暂无
暂无

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

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