Lua调用自定义C模块
Lua调用自定义C模块有两种方式:一是将C函数编译进主程序并用lua_register注册;二是编译为动态库通过require加载,动态库需包含luaopen_XXX函数。Lua5.2后改用luaL_newlib注册函数,更简洁高效。
《Lua程序设计》里讲得很清楚,但真要上手跑起来,对刚接触Lua的同学来说还是有不少坑——比如怎么生成一个动态链接库(so文件),再比如Lua 5.2之后导出函数从luaL_register换成了luaL_newlib。这些细节不捋清楚,代码就是跑不起来。下面我们拿一个具体的模块hello_lib来说事:Lua解释器会根据模块名找到对应的so文件,然后执行其中的luaopen_XXX函数。
先看C代码:
#include#include #include #include static int hello_sin(lua_State *L){ double d = luaL_checknumber(L, 1); lua_pushnumber(L, sin(d)); return 1; } static const struct luaL_Reg hello_lib[] = { {"hello_sin" , hello_sin}, {NULL, NULL} }; int luaopen_hello_lib(lua_State *L){ luaL_newlib(L, hello_lib); //luaL_register(L, "hello_lib",hello_lib); // lua 5.1 return 1; }
在Lua中调用:
local hello = require "hello_lib" print(hello.hello_sin(1))
执行过程和结果如下:

1. C函数作为应用程序的一部分
这是最直接的方式——将C函数编译进主程序,通过lua_register注册为Lua的全局函数。下面是一个完整的示例,演示如何将add2和sub2注册到Lua环境中并直接执行Lua代码片段:
#include#include #include #include #include //待Lua调用的C注册函数。 static int add2(lua_State* L) { double op1 = luaL_checknumber(L,1); double op2 = luaL_checknumber(L,2); lua_pushnumber(L,op1 + op2); return 1; } static int sub2(lua_State* L) { double op1 = luaL_checknumber(L,1); double op2 = luaL_checknumber(L,2); lua_pushnumber(L,op1 - op2); return 1; } const char* testfunc = "print(add2(1.0,2.0)) print(sub2(20.1,19))"; int main() { lua_State* L = luaL_newstate(); luaL_openlibs(L); lua_register(L, "add2", add2); lua_register(L, "sub2", sub2); if (luaL_dostring(L,testfunc)) printf("Failed to invoke.n"); lua_close(L); return 0; }
2. C函数库成为Lua的模块
更常见的做法是把C函数编译成动态库(Linux下是so,Windows下是DLL),然后放到Lua解析器能找到的路径下——比如当前目录,或者LUA_CPATH环境变量指向的目录。在Windows系统中,通常可以拷贝到C:\Program Files\Lua5.1\clibs。下面是关键代码和注释:
#include#include #include #include #include extern "C" int add(lua_State* L) { double op1 = luaL_checknumber(L,1); double op2 = luaL_checknumber(L,2); lua_pushnumber(L,op1 + op2); return 1; } extern "C" int sub(lua_State* L) { double op1 = luaL_checknumber(L,1); double op2 = luaL_checknumber(L,2); lua_pushnumber(L,op1 - op2); return 1; } static luaL_Reg mylibs[] = { {"add", add}, {"sub", sub}, {NULL, NULL} }; extern "C" __declspec(dllexport) int luaopen_mytestlib(lua_State* L) { const char* libName = "mytestlib"; luaL_register(L,libName,mylibs); return 1; }
对应的Lua调用代码:
require "mytestlib" -- 指定包名称 -- 注意:调用时必须是 package.function 的形式 print(mytestlib.add(1.0,2.0)) print(mytestlib.sub(20.1,19))
Windows 10 是一款微软推出的经典操作系统,拥有硬件兼容性与多任务处理能力。它更偏向把系统状态查看和常用调节动作放在一起,适合需要持续观察和微调设备状态的场景。
极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。
















