lua调用C语言函数,在函数中进行类型检查

ops/2024/11/20 22:47:24/
  1. 使用lua_is*函数族进行检查(除了lua_type之外的另一种方式)

    • Lua C API提供了一系列lua_is*函数,如lua_isnumberlua_isstringlua_isboolean等,用于检查栈上元素的类型。
    • 示例代码如下,假设我们有一个C函数,它期望接收一个布尔值和一个数字作为参数:
    #include <stdio.h>
    #include <lua.h>
    #include <lauxlib.h>
    #include <lualib.h>static int check_and_print(lua_State *L) {// 检查第一个参数是否为布尔值if (!lua_isboolean(L, 1)) {lua_pushstring(L, "第一个参数必须是布尔值");lua_error(L);}// 检查第二个参数是否为数字if (!lua_isnumber(L, 2)) {lua_pushstring(L, "第二个参数必须是数字");lua_error(L);}int booleanValue = lua_toboolean(L, 1);double numberValue = lua_tonumber(L, 2);printf("布尔值为: %d, 数字为: %f\n", booleanValue, numberValue);// 可以根据需要返回值给Lua,这里简单返回数字lua_pushnumber(L, numberValue);return 1;
    }
    
    • 在这里,lua_isboolean函数检查第一个参数是否是布尔类型,lua_isnumber函数检查第二个参数是否是数字类型。如果检查不通过,就会抛出错误。
  2. 联合类型检查和转换(处理多种可能的数字类型)

    • 在Lua中,数字类型可能是整数或者浮点数。当在C函数中接收数字类型参数时,可以使用联合(union)来处理不同的数字类型情况。
    • 示例代码如下,这个C函数可以接收整数或者浮点数作为第一个参数,并将其转换为浮点数进行处理:
    #include <stdio.h>
    #include <lua.h>
    #include <lauxlib.h>
    #include <lualib.h>
    #include <math.h>static int process_number(lua_State *L) {// 检查第一个参数是否是数字类型if (!lua_isnumber(L, 1)) {lua_pushstring(L, "第一个参数必须是数字");lua_error(L);}// 使用union来处理可能的整数或浮点数情况union {int i;double d;} number;if (lua_isinteger(L, 1)) {number.i = lua_tointeger(L, 1);} else {number.d = lua_tonumber(L, 1);}// 对转换后的浮点数进行简单的数学操作(这里是求平方根)double result = sqrt(number.d);lua_pushnumber(L, result);return 1;
    }
    
    • 在这个示例中,首先使用lua_isnumber检查参数是否是数字类型。然后,通过一个联合来处理整数和浮点数的转换。如果参数是整数,就使用lua_tointeger将其转换为整数存储在联合中;如果是浮点数,就使用lua_tonumber将其转换为浮点数存储在联合中。最后,对转换后的浮点数进行求平方根操作,并将结果返回给Lua。
  3. 检查表类型及表内元素类型(处理复杂数据结构)

    • 当Lua传递表(table)类型的参数给C函数时,需要检查表的类型以及表内元素的类型。
    • 以下示例是一个C函数,它期望接收一个表,表中有两个元素,第一个元素是字符串,第二个元素是数字,然后打印这两个元素并返回它们的拼接结果(字符串和数字转换为字符串后拼接):
    #include <stdio.h>
    #include <lua.h>
    #include <lauxlib.h>
    #include <lualib.h>static int process_table(lua_State *L) {// 检查第一个参数是否是表类型if (!lua_istable(L, 1)) {lua_pushstring(L, "第一个参数必须是表");lua_error(L);}// 获取表中的两个元素lua_pushinteger(L, 1);lua_gettable(L, 1);if (!lua_isstring(L, - 1)) {lua_pushstring(L, "表中的第一个元素必须是字符串");lua_error(L);}const char *str = lua_tostring(L, - 1);lua_pop(L, 1);lua_pushinteger(L, 2);lua_gettable(L, 1);if (!lua_isnumber(L, - 1)) {lua_pushstring(L, "表中的第二个元素必须是数字");lua_error(L);}double num = lua_tonumber(L, - 1);lua_pop(L, 1);printf("字符串是: %s, 数字是: %f\n", str, num);char buffer[100];sprintf(buffer, "%s%f", str, num);lua_pushstring(L, buffer);return 1;
    }
    
    • 在这个示例中:
      • 首先使用lua_istable检查第一个参数是否是表类型。
      • 然后通过lua_pushintegerlua_gettable组合来获取表中的元素。对于每个元素,使用相应的lua_is*函数检查类型。如果类型不符合要求,就抛出错误。
      • 最后,获取正确类型的元素后,进行打印操作,并将拼接后的结果返回给Lua。

http://www.ppmy.cn/ops/135345.html

相关文章

Deep-Live-Cam -面部交换、视频深度伪造

文章目录 一、关于 Deep-Live-Cam免责声明 二、安装&#xff08;Windows/Nvidia&#xff09;安装&#xff08;手动&#xff09;基本安装&#xff08;CPU&#xff09; GPU加速&#xff08;可选&#xff09;CUDA执行提供商&#xff08;Nvidia&#xff09;CoreML执行提供商&#x…

Linux系统Centos设置开机默认root用户

目录 一. 教程 二. 部分第三方工具配置也无效 一. 教程 使用 Linux 安装Centos系统的小伙伴大概都知道&#xff0c;我们进入系统后&#xff0c;通常都是自己设置的普通用户身份&#xff0c;而不是 root 超级管理员用户&#xff0c;导致我们在操作文件夹时往往爆出没有权限&am…

Java 设计模式 详解

在Java开发中&#xff0c;设计模式是一种常见的、成熟的解决方案&#xff0c;用于应对特定的设计问题和复杂性管理。以下是一些常用的设计模式&#xff0c;它们可以分为三类&#xff1a;创建型模式、结构型模式和行为型模式。 一、创建型模式 创建型模式主要负责对象的创建&a…

Android开发实战班 - Android开发基础之 Kotlin语言基础与特性

Kotlin 是一种现代化的编程语言&#xff0c;由 JetBrains 开发&#xff0c;现已成为 Android 官方支持的开发语言。相比于 Java&#xff0c;Kotlin 提供了更简洁、安全和高效的语法特性&#xff0c;极大地提升了开发效率。本章节将深入讲解 Kotlin 的基础语法和核心特性&#x…

Windows配置域名映射IP

一、找到 hosts 文件 打开 C:\Windows\System32\drivers\etc 二、添加hosts文件修改、写入权限 右击hosts文件&#xff0c;点击属性 -> 安全 -> Users -> 编辑 -> Users -> 添加修改、写入权限 -> 确定 -> 确定 进入常规&#xff0c;将只读属性关闭 三、…

【NodeJS】Node.js是什么?能做什么?

👉博主介绍: 博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家,WEB架构师,阿里云专家博主,华为云云享专家,51CTO 专家博主 ⛪️ 个人社区:个人社区 💞 个人主页:个人主页 🙉 专栏地址: ✅ Java 中级 🙉八股文专题:剑指大厂,手撕 J…

qt之QFTP对文件夹(含嵌套文件夹和文件)、文件删除下载功能

一、前言 主要功能如下&#xff1a; 1.实现文件夹的下载和删除&#xff0c;网上很多资料都是单独对某个路径的文件操作的&#xff0c;并不能对文件夹操作 2.实现目标机中含中文名称自动转码&#xff0c;有些系统编码方式不同&#xff0c;下载出来的文件会乱码 3.实现ftp功能…

Redis作为分布式锁,得会避坑

日常开发中&#xff0c;经常会碰到秒杀抢购等业务场景。为了避免并发请求造成的库存超卖等问题&#xff0c;我们一般会用到Redis分布式锁。但是使用Redis分布式锁之前要知道有哪些坑是需要我们避过去的。 1. 非原子操作&#xff08;setnx expire&#xff09; 一说到实现Redis…