You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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是错误的)
}

关键细节说明

  1. 参数校验:提前检查输入类型和合法性,避免非法输入导致程序崩溃。
  2. 内存管理:根据传入的sizeof_verts分配对应大小的内存,用于存储转换后的float数组。
  3. 类型转换:遍历Lua table,将每个double类型的顶点值转换为float,存入临时数组。
  4. 返回值修正:原绑定函数返回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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 03:35:27