【问题标题】:Best way to pass large binary data to C from Lua将大型二进制数据从 Lua 传递到 C 的最佳方法
【发布时间】:2012-10-23 18:31:11
【问题描述】:

我有一个应用程序,我通过 LuaSockets 从网络 (500KB) 获取大量二进制数据。 (还没有实现这部分)。根据我所知道的,这些数据将存储在某种字符串或表或数组中。

我需要对这些数据进行复杂处理,并且我有一个现有的、经过验证的 ANSI-C Lib,我需要将数据传递给 C。我研究过的方法通常在调用堆栈中传递数据由于数据大小,对我不起作用。

现有的 ANSI-C 库需要一个指向数据和大小的指针。我可能可以用一个新的 API 包装这个 API,它逐字节地排除数据,最后一旦确定了整个大小,就调用真正的 API,但这意味着从 Lua 对某些 C 函数的大量调用,而不是首选,因为我想要性能.

将这些大数据传递给 C 的最佳方法是什么? (我考虑过写入文件并传递文件名,但这不是首选,我真的想要直接内存传递)

【问题讨论】:

  • "据我所知,这些数据将存储在某种字符串或表或数组中。" 它是什么?这是 3 种完全不同的东西。
  • @NicolBolas 这本身就是另一个问题 Nicol。 Lua的类型不是很严格,我基本不知道。但根据我阅读的内容,它似乎已连接:receive([size]) 以字符串格式返回数据报。
  • 请注意,虽然 LuaSocket 确实在 Lua 字符串中传递二进制数据(顺便说一句,这是完全支持和推荐的做法),但它不能保证任何特定的调用都会产生整个数据报。此外,如果您要移动 500KB,它肯定不会收集那么大的缓冲区以在一次调用中返回。您将希望从receive() 返回的字符串逐步构建数据主体。一种好方法是将它们收集在一个表中并将整个表传递给 C 端。

标签: c lua


【解决方案1】:

假设 LuaSocket 以字符串的形式提供数据,那真的很简单。

您的 C 应用程序将直接从 Lua 传递字符串。所以它在 Lua 堆栈上。使用lua_tolstring 获取字符串及其大小。这将返回一个指向 Lua 拥有的内存的指针(因此您需要确保它保留在 Lua 堆栈或注册表中或在您使用它的某个地方,以防止 Lua 垃圾收集它)。然后将该字符串+大小传递给您选择的 API。

【讨论】:

    【解决方案2】:

    在我看来,您不必关心 Lua 堆栈的大小。 Lua 堆栈上的大多数(如果不是每个)元素实际上都是堆分配的。如果你使用的是 luasocket,那么你收到的二进制数据已经可以作为 Lua 字符串使用(我猜是 socket:receive 的返回值),所以你没有额外分配任何东西! Lua 堆栈实际上更有可能传递某种引用,因此不会发生复制或者非常便宜。 要连接您的 C lib,您可以: a) 编写一个 C 绑定 b) 使用外星人 c) 卢吉特 在 99% 的情况下,我更喜欢 a)。有几种方法可以做到这一点,但它似乎是一个相当苗条的 C API,所以我会在没有任何额外绑定库(如 luabind)的情况下做到这一点。

    您可以查看 lua-cjson 源代码http://www.kyne.com.au/~mark/software/lua-cjson-manual.html。这是一个很好的 C 绑定示例。

    【讨论】:

      【解决方案3】:

      如果我是你的情况,我会跳过 luasocket,而只使用 C/C++ 套接字库。

      由于无论如何处理都将在 C/C++ 中完成,因此使用 luasocket 简化了(一点)套接字处理,但代价是接收数据和 C/C++ 二进制数据处理库之间的接口(显着)复杂化.

      使用 C/C++ 套接字库会使套接字处理更加困难(但不会太多),而将数据传输到处理库将是微不足道的。

      【讨论】:

      • 好的。我尊重你的观点。我坚持使用 LUA 的原因是 LUA 的跨平台兼容性。 (Android vs. iOS)我现在将 MOAI 和 Gideros 视为潜力。我真的不想移植整个 UI 和体验,因此是当前的想法。您是否知道任何跨平台 C/C++ 套接字库?
      • 我不明白。如果您使用的是 MOAI 或 Gideros,您打算如何使用 C/C++ 数据解析库?
      • MOAI 和 Gideros 都很好地与 C 集成,在 Gideros 上更简单。我做复杂工作的引擎是用C写的,所以我基本上用C做所有复杂的计算和数据解析,然后把结果传回LUA。 LUA 将运行 box2D 和其他 UI 元素和界面。我真的不想跨平台接触 UI 代码,这是我使用这个交叉开发工具的主要动机。
      • 在这种情况下,我建议你只使用 LuaSocket 的 C 部分——它是一个双库,有一个 C 部分和一个 Lua 部分。你的 C/C++ 肯定可以用它的 C 说话。而且由于它是一个相对流行的库,有人可能会在 Gideros/MOAI 上有一些使用它的经验,所以如果你遇到困难,你可能会寻求帮助。 (免责声明:我没有这样尝试过,但我认为它可以工作)
      • 有趣的想法..好的,我会试一试。
      猜你喜欢
      • 1970-01-01
      • 2014-12-01
      • 2010-09-22
      • 2011-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-28
      相关资源
      最近更新 更多