如何使用 cffi-lua 向/从 C 函数传递 Lua 表

Posted

技术标签:

【中文标题】如何使用 cffi-lua 向/从 C 函数传递 Lua 表【英文标题】:How do I pass a Lua Table to/from a C function using cffi-lua 【发布时间】:2021-12-22 03:39:26 【问题描述】:

我在 Ubuntu 21.10 上使用 Lua 5.4.3 而不是 LuaJIT/FFI,而是使用 cffi-lua

如果C函数是

ffi.cdef [[
   void dummy(int* ptr_form_lua, int size)
]]

Lua 表是

local mytable = 2,4,6,8 --as if an array of ints

我如何将它传递给/从 C 函数

【问题讨论】:

这能回答你的问题吗? LuaJIT ffi : How to pass array of string to c function ffi.C.execvp 运行一个可执行文件,而我的 dummy() 是加载库中的一个过程 execvp 也是加载库中的一个过程;-) 您需要创建 int 的 FFI 数组并使用您的 Lua 表对其进行初始化(与为 @ 初始化 char* 数组的方式相同) 987654326@). 好的,现在知道了。我确实在搜索的早些时候找到了那个帖子,但是“ls -al”让我很困惑。 【参考方案1】:

如果像我这样的其他人对上面附加帖子中的答案感到困惑,这里是一个将 Lua 表传递给 C 库的完整工作示例。 关键是要知道 Lua 中的数字是 C 中的双精度数 如果这不是最佳解决方案,我相信有人会告诉我/我们!

--Lua 代码,v5.4.3 使用 Ubuntu 21.10

#!/usr/bin/env -S lua -W

-- Require cffi-lua, not from luaJIT
-- via LuaRocks, with LUA_CPATH set
local cffi = require("cffi")

-- Load libfoo
local mylib = cffi.load('./libfoo.so')

-- Function prototype definitions
cffi.cdef [[
   //int gettable(const char *file, const char **datav); //Original
   int getStable(const char **data);
   int getItable(const double *data, int size);
]]

-- Main program ------------------------------------
print("Test Program!")

local data1 = cffi.new("const char*[3]", "ls", "-lsdfsdf") --original, works

--from a Lua Table
local mytableS = "string one", "string two", "string three"
local mytableSlen = #mytableS
local mytableSCstruct = "const char*[" .. mytableSlen + 1 .. "]"
local mytableSCuserdata = cffi.new(mytableSCstruct, mytableS)
print(type(mytableSCuserdata))
local ret = mylib.getStable(mytableSCuserdata)
print(ret)

--from a Lua Table, where it is necessary to know that Lua Numbers
-- are Doubles in C
local mytableI = 12,23,34,45,56,67,78,89,91,120, 3.142, 2.71828
local mytableIlen = #mytableI
local mytableICstruct = "const double[" .. mytableIlen .. "]"
local mytableICuserdata = cffi.new(mytableICstruct, mytableI)
print(type(mytableICuserdata))
local ret = mylib.getItable(mytableICuserdata, mytableIlen)
print(ret)

print("Bye!")

C 库代码,编译时使用 gcc foo.c -shared -fPIC -std=c11 -o libfoo.so

/***************************************
  library
***************************************/
#include <stdio.h>
#include <stdlib.h>

//Using Strings
int getStable(const char **data)

  printf("In S GetTable\n");
  for (const char **item = data; *item; ++item)
  
    printf("Processing Item: %s\n", *item);
  
  //not used
  return 0;


//Using Doubles
int getItable(const double *data, int size)

  printf("In I GetTable, with size: %d\n", size);
  for (int i = 0; i < size; i++)
  
    printf("Processing Item: %lf\n", data[i]);
  
  //not used
  return 0;

【讨论】:

以上是关于如何使用 cffi-lua 向/从 C 函数传递 Lua 表的主要内容,如果未能解决你的问题,请参考以下文章

C语言函数传递二维数组

如何向 Shader 传递一个巨大的数组

如何将委托或函数指针从C#传递给C ++并使用InternalCall在那里调用它

c语言向函数传递函数作为参数

如何将函数作为参数从 C 传递到 C++ 并返回到 C

向函数传递字符串