Lua调用c模块

作者: print("") 分类: 信息安全 发布时间: 2021-06-18 18:10

一、lua调用c模块总结
1.c函数库成为lua的一个模块
主要做法:将包含c函数的代码生成库文件 linux下是.so  windows下是.dll 
          同时拷贝到lua运行环境的bin下(由于我用的是LuaTool运行环境 所以放在bin下 程序运行默认从bin下找)
          这样lua解析器才可以找到.dll文件 
2.编写c模块
  (1)先编写需要注册的c函数 这些c函数用统一的声明并且必须写为static 返回置为int
  (2)定义luaL_Reg结构体 这个结构体数组用来因为注册到Lua模块中
     luaL_Reg结构体的第一个字段为字符串 在注册时通知lua该函数的名字
    第二个字段为函数指针
    最后一个永远为NULL 用来标记结尾
  (3) __declspec(dllexport)将函数、类等声明为导出函数,供其它程序调用,作为动态库的对外接口函数、类等
      这个函数非常重要 如果没有 将来生成的.dll不能够被lua模块找到
  (4)向lua中注册上述的表格

(5)C相关的API

typedef struct lua_State lua_State  lua解释器 
typedef int (*lua_CFunction)(lua_State *L) 能够别Lua调用的C函数必须是这种规则 函数的返回值int值表示C函数返回值的个数
void lua_pushcclosure(lua_State*L,lua_CFunction fn ,int n) 将一个C必包压栈 fn C函数指针 n 函数关联的upvalue的个数 首先将upvalues依次压栈 然后调用该函数 将C函数压栈 并将n个upvalues出栈
void lua_pushcfunction(lua_State*L,lua_CFunction fn )将c函数压栈 接收一个c函数的指针 然后将Lua.function类型的对象压栈
void lua_register(lua_State*L,const char *name, lua_CFunction f) 注册C函数为一个全局变量
void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup);
注册函数到栈顶的表中;
参数l:luaL_Reg列表,记录了要注册的函数信息,注意,该列表以{NULL, NULL}结尾;
nup参数:upvalue的个数,如果不为0,则注册的所有函数都共享这些upvalues;
先将table压栈,然后将upvalues依次压栈,然后调用该函数进行函数注册。注册完毕后upvalues会出栈。
注意:luaL_register函数已经不再使用,取而代之的是luaL_setfuncs,因为该函数不会创建全局变量。
    举例如下 mycomplib.c

从C value —> lua Value  并不是简单地将值通过栈传给lua 而是将其封装成一个table 其中会放生 栈顶新分配元素 绑定或者赋值

一个c value入栈就是进入了lua的世界, lua会生成一个对应的结构并管理起来, 从此就不再依赖这个c value

mycomplib.c

#include <stdio.h>
#include <stdlib.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
 
static int add(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},
	{NULL,NULL}
};

// __declspec(dllexport);
 
int luaopen_mycomplib(lua_State* L)
{
	const char *libName = "mycomplib";
	luaL_register(L, libName, mylibs);
	return 1;
}

test_c.lua

mycomplib=require "mycomplib"

function help()
	print("you maybe input: lua [script] -d filename1 -f filename2")
end
 
function main()
	
   aaa=mycomplib.add(10,10)
    print(aaa)
	--print(mycomplib.add(10,20))
end
main()

编译SO文件

gcc -c -fPIC -o mycomplib.o -I /usr/include/lua5.1/   mycomplib.c 
gcc -shared -o mycomplib.so mycomplib.o

总结。

对于__declspec这个函数。在测试中。好像并没有感觉到他的意义


参考文章:https://github.com/TheKingOfDuck/Loki

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注