如何将 Lua 函数传递给 C 函数并多次执行 Lua 函数?

2023-12-29

我想要做的是创建一个函数,它将迭代一些对象并为每个函数调用一个函数。我使用的是 BlitzMax,而不是 C,但这不是重点,因为它具有 Lua 的 C 函数的完整包装。 Lua有一个lua_pushcfunction()命令,但是lua_pushfunction()命令在哪里呢?调用具有名称的函数非常容易,但是如何调用作为参数传递的函数呢?

就像是:

ForEach( PlanetList, function (planet)
    if(planet.exists == true) then
        Planet_Count = Planet_Count + 1
    end
end )

通常你只需说“lua_getglobal(L,name)”,它就会把 lua 函数很好地放在堆栈上,但是你如何从参数中获取它呢?

EDIT

我回去并实际尝试使用luaL_ref() from 这个问题我之前发现 https://stackoverflow.com/questions/1416797/reference-to-lua-function-in-c-c。我正在做的是使用 luaL_ref() 从堆栈顶部弹出函数值并将其放入临时寄存器中,我使用从返回的值luaL_ref() to use lua_rawgeti()对于列表中的每个项目。然后用了luaL_unref()列表完成后释放该寄存器。


因为我自己也是 Lua 新手,所以我也有同样的问题。在我看来,因为没有令人满意的答案,所以我想我会写一个,即使这个问题可能永远不会结束。希望这会对其他人在这种情况下有所帮助。

main.c

#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>

/* this keeps our Lua reference to the Lua function */
int callback_reference = 0;

/* this is called by Lua to register its function */
int lua_registerCallback( lua_State *L ) {

  /* store the reference to the Lua function in a variable to be used later */
  callback_reference = luaL_ref( L, LUA_REGISTRYINDEX );

  return 0;
}

/* calls our Lua callback function and resets the callback reference */
void call_callback( lua_State *L ) {

  /* push the callback onto the stack using the Lua reference we */
  /*  stored in the registry */
  lua_rawgeti( L, LUA_REGISTRYINDEX, callback_reference );

  /* duplicate the value on the stack */
  /* NOTE: This is unnecessary, but it shows how you keep the */
  /*  callback for later */
  lua_pushvalue( L, 1 );

  /* call the callback */
  /* NOTE: This is using the one we duplicated with lua_pushvalue */
  if ( 0 != lua_pcall( L, 0, 0, 0 ) ) {
    printf("Failed to call the callback!\n %s\n", lua_tostring( L, -1 ) );
    return;
  }

  /* get a new reference to the Lua function and store it again */
  /* NOTE: This is only used in conjunction with the lua_pushvalue */
  /*  above and can be removed if you remove that */
  callback_reference = luaL_ref( L, LUA_REGISTRYINDEX );
}

int main( void ) {

  /* set up Lua */
  lua_State *L = lua_open();
  luaL_openlibs( L );

  /* register the lua_registerCallback function as */
  /*  "RegisterCallback" so it can be called by Lua */
  lua_pushcfunction( L, lua_registerCallback );
  lua_setglobal( L, "RegisterCallback" );

  /* run our Lua file */
  if ( 0 != luaL_dofile( L, "callback.lua" ) ) {
    printf("Failed to load calback.lua!\n %s",
      lua_tostring( L, -1 ) );
    lua_close( L );
    return 1;
  }

  /* call the callback */
  call_callback( L );

  /* call the callback again if you want (because we restored */
  /*  the Lua function reference) */
  call_callback( L );

  /* remove the reference to the callback */
  /* NOTE: This is also unnecessary if you didn't re-add the */
  /*  function to the registry */
  luaL_unref( L, LUA_REGISTRYINDEX, callback_reference );

  /* uninitialize Lua */
  lua_close( L );

  return 0;
}

回调.lua

function MyCallback()
  print("Hello World!")
end

RegisterCallback( MyCallback )
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将 Lua 函数传递给 C 函数并多次执行 Lua 函数? 的相关文章

随机推荐

  • SQL Server 可以向程序推送消息吗?

    SQL Server 可以将消息推送到监听 SQL Server 的程序吗 例如 有一个程序A 监听SQL Server SQL Server会查看一个名为B的表 当B有一些数据时 SQL Server会获取数据并将其推送到A 是的 这是可
  • 我们能得到 lambda 参数的类型吗?

    Using std function 我们可以使用以下方法获取参数的类型argument type second argument type等等 typedef 但我看不到用 lambda 做同样事情的方法 是否可以 我用的是VS2010
  • 反向重用 CSS 动画(通过重置状态?)

    我在 CSS 中使用了两个关键帧动画 一个从左向右移动 另一个使用完全相同的值 但方向相反 keyframes moveLeft from transform translate3d 50px 0 0 to transform transl
  • 在 React 中 e.target.value 返回未定义的问题

    我有一个功能 您可以单击一个图像并查看可单击的名称列表 当您单击一个名称时 该人的图像应该取代原始图像 我正在使用艺术家 api 而不是在控制台中收到错误 图像更改为名称为 未定义 的艺术家的 img 奇怪 可能不是一个巨大的修复 但我已经
  • 从 javascript 调用 Winform 托管的 WCF 服务

    我有一个带有 Ajax Web 端点的 Winform 托管 WCF 服务 我还有一个单独的 ASP NET 项目 页面上有 ScriptManager 组件 我的问题是 如果我使用 javascript 从 ASP NET 应用程序的客户
  • 在 LLVM IR 中插入 GetElementpointer 指令

    我想知道如何通过 LLVM Pass 在 LLVM IR 中插入 GetElementPointer 指令 假设我有一个数组 arr4 alloca 100000 x i32 align 4 并想要插入一个像 arrayidx getele
  • 一个元素上的多个 jQuery 事件具有不同的功能和目标选择器

    有没有办法结合这两种方法来处理 jQuery 中的事件附件 selector on mouseenter function mouseleave function mousedown function mouseup function 我更
  • 使用 Interlocked 测试并有条件地更新 long

    有没有一种巧妙的方法可以使用Interlocked班级 或者我应该使用lock 我的具体用例是我有多个线程来计算long值 并将其与共享 最大值 值进行比较 仅当本地值较大时才替换共享值 Try the Interlocked Compar
  • React-Final-Form 在子组件中带有 DropDown,怎么样?

    我正在尝试在子组件中使用带有 DropDown 的 React final form 无法让这个工作 我的所有文本字段都已经在子组件中 这就像一个魅力 父级中的字段如下所示
  • C++、cin、cout、threads 和sync_with_stdio 的输出损坏

    我正在尝试用 C 编写一个程序 以尽可能最快的方式处理大量数据包 来自标准的所有数据包都应尽快读取 发送到池中的一个线程进行处理 然后处理到将数据包写入标准输出的输出线程 当您在 C 中使用标准输入和输出时 建议在任何输入或输出之前调用st
  • 放弃 Git Stash Pop

    我做了一个 git stash pop 现在有很多冲突 我在之前提交了所有最近的代码git stash pop 那么有没有办法返回到最后一次提交并消除所有冲突并编码git stash pop注射 这个问题已经在 stackoverflow
  • 如何从会话中检索通用列表?

    我在会议中列出了一份清单 Session Add SessionList mylist 如何从会话中检索它 var list Session SessionList as List
  • Appengine 过滤不等式和排序失败

    我认为我在这里忽略了一些简单的事情 我无法想象这是不可能做到的 我想按日期时间属性进行过滤 然后按排名整数属性对结果进行排序 当我尝试这样做时 query filter submitted gt thisweek order ranking
  • 从 JSON 到 NSArray

    我正在使用此处找到的 JSON 框架 http stig github com json framework http stig github com json framework在我的 iPhone 应用程序中 我正在尝试将一些数据解析为
  • 这是 Ruby 中 Array.fill 方法的错误吗? [复制]

    这个问题在这里已经有答案了 应该是这种情况 即我误解了 还是一个错误 a Array new 3 Array new 3 a 1 fill g gt g g g g g g g g g 不应该导致 gt nil nil nil g g g
  • 批处理文件从txt文件中删除前18个字符

    我有一个 txt 文档 其中包含超过 32 000 行带注释的机器代码 它看起来像这样 Display menu window C0 000E E220 SEP 20 C0 0010 C210 REP 10 C0 0012 20640B J
  • HostnameVerifier 接口的不安全实现 - Android

    Play 商店应用被拒绝的原因 您的应用程序正在使用 HostnameVerifier 接口的不安全实现 您可以在此找到有关如何解决该问题的更多信息Google 帮助中心文章 https support google com faqs an
  • grep 查找中间带有通配符的文本

    我想 grep 类似的东西 gt sh lt 但这不起作用 我可以 grep 一切 sh lt 但无法让通配符发挥作用 这里有什么技巧呢 你需要 grep 类似的东西 gt sh lt The 部分匹配任何长度的任何字符 部分匹配一个点
  • gwt 自定义小部件包装方法

    我的自定义小部件如下所示 public class CustomWidget extends Composite public static CustomWidget wrap com google gwt dom client Eleme
  • 如何将 Lua 函数传递给 C 函数并多次执行 Lua 函数?

    我想要做的是创建一个函数 它将迭代一些对象并为每个函数调用一个函数 我使用的是 BlitzMax 而不是 C 但这不是重点 因为它具有 Lua 的 C 函数的完整包装 Lua有一个lua pushcfunction 命令 但是lua pus