如何将Lua数组传入C函数mesh_create_default并转为float*?
解决Lua向C传递顶点数组并完成double到float转换的问题
问题分析
当前绑定函数错误地使用lua_touserdata读取Lua中的table(顶点数组),这完全不符合Lua与C交互的规则——Lua的table并非userdata。同时需要将Lua默认的double类型数值转换为C函数所需的float类型,且要在C端完成转换以简化Lua脚本。
修正后的绑定函数代码
#include <lua.h> #include <lauxlib.h> #include <stdlib.h> #include <stdint.h> // 假设已有的核心函数声明 void *mesh_create(); void mesh_data(void *mesh, float *verts, uint32_t sizeof_verts); void *mesh_create_default(float *verts, uint32_t sizeof_verts); int Lmesh_create_default(lua_State *L) { // 参数合法性校验 if (!lua_istable(L, 1)) { return luaL_error(L, "第一个参数必须是顶点数组table"); } uint32_t sizeof_verts = (uint32_t)lua_tointeger(L, 2); if (sizeof_verts % sizeof(float) != 0) { return luaL_error(L, "sizeof_verts必须是float大小的整数倍"); } size_t float_count = sizeof_verts / sizeof(float); // 分配内存存储转换后的float数组 float *verts = (float*)malloc(sizeof_verts); if (!verts) { return luaL_error(L, "无法分配顶点内存"); } // 遍历Lua table,将double转为float for (size_t i = 0; i < float_count; i++) { lua_pushinteger(L, i + 1); // Lua table索引从1开始 lua_gettable(L, 1); if (!lua_isnumber(L, -1)) { free(verts); return luaL_error(L, "顶点数组第%zu个元素不是数字", i + 1); } double val = lua_tonumber(L, -1); verts[i] = (float)val; lua_pop(L, 1); // 弹出当前元素,清理栈 } // 调用原C函数 void *mesh = mesh_create_default(verts, sizeof_verts); // 释放临时内存:若mesh_data已拷贝顶点数据则可释放;若mesh_data仅保存指针则不能释放(需后续绑定销毁逻辑) free(verts); // 将mesh指针转为uint64_t返回Lua lua_pushinteger(L, (uint64_t)mesh); return 1; // 必须返回1,告诉Lua有1个返回值(原代码返回0是错误的) }
关键细节说明
- 参数校验:提前检查输入类型和合法性,避免非法输入导致程序崩溃。
- 内存管理:根据传入的
sizeof_verts分配对应大小的内存,用于存储转换后的float数组。 - 类型转换:遍历Lua table,将每个double类型的顶点值转换为float,存入临时数组。
- 返回值修正:原绑定函数返回0,但实际向Lua栈中压入了结果,必须返回1才能让Lua正确获取返回值。
原C函数的潜在问题修正
原mesh_create_default存在两个严重问题:
// 原错误代码 void *mesh_create_default(float *verts, uint32_t sizeof_verts) { static void *mesh; // 静态变量导致多次调用共享同一个指针 mesh = mesh_create(); mesh_data(mesh, verts, sizeof_verts); return &mesh; // 返回的是静态指针的地址,而非mesh本身 }
修正为:
void *mesh_create_default(float *verts, uint32_t sizeof_verts) { void *mesh = mesh_create(); // 去掉static,每次调用创建独立的mesh mesh_data(mesh, verts, sizeof_verts); return mesh; // 返回mesh本身的指针 }
Lua端调用保持不变
你的Lua脚本无需任何修改,绑定层已完成所有转换逻辑,符合简洁性需求:
Verts = { 0.0, 1.0, 0.0, 1.0, -1.0, 0.0, -1.0, -1.0, 0.0, } function Ready() Mesh = mesh_create_default(Verts, 4 * 3 * 3) end
内容的提问来源于stack exchange,提问作者Snail5008
相关产品推荐
相关产品推荐

