当前位置: 首页 > news >正文

Lua调用c语言的函数

未测试
lua只识别动态库,c语言需要编译被调用模块,然后编译成动态库。

那么lua怎么识别c语言的动态库的函数呢?lua只识别以luaopen开头的函数。


 

5.4、完整示例代码
注意:在Linux上直接使用apt-get安装的lua是没有自动安装lua库的,需要下载lua的源码编译安装。

tbl.c

#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include <stdio.h>static int
lecho (lua_State *L) {const char* str = lua_tostring(L, -1);fprintf(stdout, "%s\n", str);return 0;
}static const luaL_Reg l[] = {// 导出给lua使用数组{"echo", lecho},{NULL, NULL},
};int
luaopen_tbl_c(lua_State *L) { // local tbl = require "tbl.c"// 创建一张新的表,并预分配足够保存下数组 l 内容的空间// luaL_newlibtable(L, l);// luaL_setfuncs(L, l, 0);
    luaL_newlib(L, l);return 1;
}

 

test.lua

package.cpath = "luaclib/?.so"
local so = require "tbl.c"function Init(args)print("call [init] function", args)
endfunction Loop()print("call [loop] function")for k, v in ipairs({1,2,3,4,5}) doso.echo(v)end
endfunction Release()print("call [release] function")
end

 

 


Makefile示例:
代码语言:Bash

# $@ 目标文件 $^ 所有的依赖文件 $< 第一个依赖文件
# -Wl,-E
PLAT ?= linux
# 在Makefile中,.PHONY后面的target表示的也是一个伪造的target, 而不是真实存在的文件target;
# 注意Makefile的target默认是文件。 shell
.PHONY : clean all cleanall
LUA_CLIB_PATH ?= luaclib
LUA_CLIB_SRC ?= lualib-src
# LUA_CLIB = tbl uv reg1 reg2 ud
LUA_CLIB = tbl
LUA_INC ?= ./lua/src
SHARED := -fPIC --shared
EXPORT := -Wl,-Eifeq ($(PLAT), macosx)SHARED := -fPIC -dynamiclib -Wl,-undefined,dynamic_lookup
endifCFLAGS = -g -O2 -Wall -I$(LUA_INC)CC ?= gccLUA_STATICLIB := lua/src/liblua.a



all : \$(LUA_STATICLIB) \test-vm \$(foreach v, $(LUA_CLIB), $(LUA_CLIB_PATH)/$(v).so)$(LUA_STATICLIB) :cd lua && $(MAKE) CC='$(CC) -std=gnu99' $(PLAT) test-vm : test-vm.c$(CC) $(CFLAGS) $^ -o $@ -L$(LUA_INC) $(EXPORT) -llua -ldl -lm$(LUA_CLIB_PATH) :mkdir -p $(LUA_CLIB_PATH)$(LUA_CLIB_PATH)/tbl.so : $(LUA_CLIB_SRC)/lua-tbl.c | $(LUA_CLIB_PATH)$(CC) $(CFLAGS) $(SHARED) $^ -o $@ clean:rm -f $(LUA_CLIB_PATH)/*.sorm -f test-vm cleanall :rm -f $(LUA_CLIB_PATH)/*.socd lua && $(MAKE) cleanrm -f test-vm

 

 


5.1、原理
1. c语言编写模块,编译成动态库。
2. lua加载c语言的动态库:.so,.dll,.dylib
3. 约定读取动态库中以luaopen_*命名的函数。
4. lua获取模块对象后,通过函数名可以找到c函数地址,从而调用c代码

 


 

5.2、实现步骤

(1)c语言中实现一个函数。

static int
lecho (lua_State *L) {const char* str = lua_tostring(L, -1);fprintf(stdout, "%s\n", str);return 0;
}

 

(2)创建一个导出给lua使用的数组,类型是luaL_Reg。

static const luaL_Reg l[] = {// 导出给lua使用数组{"echo", lecho},{NULL, NULL},
};

 


(3)c语言实现一个luaopen开头的函数,创建一张新的表,并预分配足够保存下函数指针数组内容的空间。

int
luaopen_tbl_c(lua_State *L) { // local tbl = require "tbl.c"// 创建一张新的表,并预分配足够保存下数组 l 内容的空间// luaL_newlibtable(L, l);// luaL_setfuncs(L, l, 0);
    luaL_newlib(L, l);return 1;
}

 


(4)lua中导入c语言动态库并使用函数。

package.cpath = "luaclib/?.so"
local so = require "tbl.c"

 


(5)编译c语

 


5.3、从lua角度看调用过程
(1)lua首先会进行动态库的导入,即

local so=require "table.c"

 

(2)Lua就会去查找动态库中以luaopen_*开头的函数,*就是展开了的c文件名,比如展开为luaopen_table_c的函数名。

(3)找到函数后就执行函数,函数里面新建了一张函数地址表(函数数组),然后以table形式传给变量so。

(4)接下来就可以使用c语言的函数了。

 


 

http://www.jsqmd.com/news/128350/

相关文章:

  • OpenSpeedy错误代码全面解析:从诊断到修复的完整指南
  • 2025年工厂短视频宣传服务商推荐:工厂短视频推广权威公司TOP5榜单 - myqiye
  • PCB晶振常见故障分析与解决方案,新手必看
  • 3个核心功能:SMUDebugTool让Ryzen系统调试变得如此简单
  • 宝塔面板安装教程
  • 3分钟快速上手XHS-Downloader:小红书内容高效下载与数据导出实战
  • WinAsar:终极免费asar文件处理工具,图形化操作简单如画图
  • ABC436 题解
  • Nintendo Switch NAND管理专家:NxNandManager深度使用教程
  • 2025百度SEO服务商严选:避坑指南+5大实战派机构推荐,精准获客率超75%
  • 想在湖南省衡阳市农村盖房子,靠谱的自建房设计公司口碑推荐 - 苏木2025
  • League Director终极指南:打造专业级英雄联盟回放视频
  • XHS-Downloader小红书内容采集与数据导出完整指南
  • 人人都是产品经理 学习笔记
  • 2025年GEO优化公司综合实力测评排名:技术深度与商业成效双维度权威TOP5榜单
  • 注意!2026年《中科院分区表》和《国际期刊预警名单》将发布
  • 2025年GEO优化服务商实测测评:权威选TOP5榜单推荐
  • 抖音创作者内容批量采集终极指南:三步实现自动化视频下载
  • 2025年行业内正规的方形横流冷却塔品牌怎么选购,冷却塔/工业冷却塔/方形横流冷却塔/圆形逆流冷却塔/方形横流冷却塔制造厂家如何选 - 品牌推荐师
  • 2025 拉萨轿车托运全场景体验指南:5 大品牌评分对比,鹏宇 9.98 分最适配藏区 - 品牌智鉴榜
  • 多平台直播录制工具终极完整指南:一键搭建智能监控系统
  • 从零实现I2C HID设备调试:解决启动代码10的实操步骤
  • https://doc.dcloud.net.cn/uni-app-x/app-harmony/
  • 2025年靠谱的周转箱用户好评厂家推荐 - 行业平台推荐
  • 湖南省邵阳市自建房设计公司/机构权威测评推荐排行榜 - 苏木2025
  • 如何快速解决OpenSpeedy常见故障:实用排查指南全解析
  • 工业4.0场景下智能蜂鸣器电路的发展趋势分析
  • 【生产力工具】Ollama 下载安装教程:从零构建本地大模型运行环境 (含模型路径修改) - PC修复电脑医生
  • 滴滴企业版携手纷享销客:以CRM重构企业出行服务新体验
  • Apache Parquet 优势与日志应用场景解析