我可以如何使用LuaJIT FFI创建一个指向已有的数据的指针?

我知道有一些使用LuaJIT FFI创建指针的示例,但大多数这些示例都没有指向现有数据。 其中一个示例在这里: 如何将指针传递给LuaJIT ffi以用作输出参数?

我还没有成功地创建指向现有值的指针。据我所知,为了拥有指针类型,我必须知道将来我想将指针指向它,如下所示:

local vao = ffi.new("GLuint[1]")
gl.GenVertexArrays(1, vao)
gl.BindVertexArray(vao[0])

在这里,我知道glGenVertexArrays需要指向vao的指针,所以我将其指定为GLuint \ [1 ]。 在C中,我会执行以下操作:

GLuint vao;
glGenVertexArrays(1,&vao);
glBindVertexArray(vao);

在这里,我不知道我将需要指向vao的指针,因此我可以按通常方式指定它。

换句话说,有没有办法获取现有值的地址或创建指向现有值的指针? 我必须预见到我将在值创建之前执行什么操作吗?

谢谢!

点赞
用户646619
用户646619

在 FFI 中无法获得指向 cdata 对象的指针。

我记得在 LuaJIT 邮件列表中阅读过,这样做是为了让一些优化能够生效,但是我在邮件列表中的存档中找不到确切的消息。

到目前为止,我还没有需要获取 cdata 对象指针的需求;LuaJIT 通过引用(类似于表)引用 cdata,并且 type[1] 技巧适用于输出参数。

2014-06-09 04:12:26
用户1436359
用户1436359

我可以使用一个 C 函数来复制 cdata 指针,代码如下:

void cdataToPointer(void *cdata, void **pointer) {
    *pointer = cdata;
}

// ...

void *mycdata = NULL;

lua_pushlightuserdata(L, &mycdata);
lua_setglobal(L, "__TEMP_USERDATA__");

luaL_dostring(L,
     "local ffi = require'ffi'\n"
     "ffi.cdef[[\n"
     "  void cdataToPointer(void *cdata, void **pointer);\n"
     "]]\n"
     "ffi.C.cdataToPointer(mycdata, __TEMP_USERDATA__)\n");
2015-05-12 08:47:11
用户1625272
用户1625272

无法获取 cdata 对象地址的原因是因为所有的 cdata 对象都是垃圾回收的。如果你仔细想一想,你就会发现这意味着它们必须分配在 Lua 堆上,而不是普通的 C 堆,如 malloc 所使用的堆。只是返回指针到 Lua 堆是极其不安全的,因为垃圾收集器随时可能移动对象。

其中一个结果是你绝对不应该像 rraallvv 建议的那样去做,因为你可能会导致段错误。

当你调用 ffi.new("GLuint[1]") 时,你在 Lua 堆上分配了一个 GLuint 数组(LuaJIT 将其称为“引用”类型)。这是 _可以的_,因为在调用 GenVertexArrays() 时,(1) 垃圾收集器无法运行,因为你正在执行 C 代码,(2) GenVertexArrays() 不会保留指针,因此你不必担心稍后访问过时的指针。

然而,LuaJIT 的 FFI 提供了足够的功能,可以构建自己的分配机制。下面的代码应该(没有完全测试过这个版本)在 C 堆上分配数据并安装一个默认的终结器来释放它。如果你查找所有使用的 FFI 函数,你应该更好地了解它们。

local function SafeHeapAlloc(typestr, finalizer)
  -- 以 free 作为默认终结器
  if not finalizer then finalizer = ffi.C.free end

  -- 自动从基本类型构造指针类型
  local ptr_typestr = ffi.typeof("$ *", typestr)

  -- 需要分配多少字节?
  local typesize    = ffi.sizeof(typestr)

  -- 进行分配并将指针结果转换类型
  local ptr = ffi.cast(ptr_typestr, ffi.C.malloc(typesize))

  -- 安装终结器
  ffi.gc( ptr, finalizer )

  return ptr
end
2015-05-27 02:46:00