lua结合c/c++ && lua调用c动态库 && lua调用c动态库
lua结合c/c++ 示例
lua调用c动态库 示例
lua调用c++动态库 示例
lua部分
#!/bin/lua
mystr="I'm lua"
myTable={name="xiaoming",id=12345}
function print_hello()
print("hello world")
end
function _add(a,b)
return a+b
end
C/C++
- 方式一引入包含lua头文件的.h文件
#ifndef MLUA_H_
#define MYLUA_H_
extern "C"
{
#include <luajit-2.0/lua.h>
#include <luajit-2.0/lauxlib.h>
#include <luajit-2.0/lualib.h>
}
#endif
#include <iostream>
#include <string>
//方式二 #include <luajit-2.0/lua.hpp>
#include "mylua.h"
using namespace std;
int main()
{
lua_State *L = luaL_newstate();
if(NULL == L)
{
cout<<"Lua 初始化失败"<<endl;
return -1;
}
// 加载相关库文件
luaL_openlibs(L);
// 加载lua文件
if(luaL_loadfile(L,"./data1.lua"))
{
cout<<"Lua 文件加载失败"<<endl;
}else{
// 执行lua文件
if(lua_pcall(L,0,0,0))
{
cerr<<lua_tostring(L,-1)<<endl;
}else{
// 获取值
lua_getglobal(L,"mystr");
string str = lua_tostring(L,-1);
cout<<str<<endl;
// 获取表中的数据
lua_getglobal(L,"myTable");
lua_getfield(L,-1,"name");
cout<<lua_tostring(L,-1)<<endl;
lua_getglobal(L,"myTable");
lua_getfield(L,-1,"id");
cout<<lua_tonumber(L,-1)<<endl;
// 调用函数
lua_getglobal(L,"print_hello");
lua_pcall(L,0,0,0);
// 调用计算函数
lua_getglobal(L,"_add");
lua_pushnumber(L,10);
lua_pushnumber(L,29);
if(lua_pcall(L,2,1,0))
{
cout<<lua_tostring(L,-1)<<endl;
lua_close(L);
}else{
if(lua_isnumber(L,-1))
{
cout<<lua_tonumber(L,-1)<<endl;
}
}
}
}
lua_close(L);
return 0;
}
lua调用c动态库
- 总结了几条要点
- 动态库要供LUA调用的function,其定义要符合:
- typedef int function(lua_State *L)
- 在动态库调用LUA注册,将要调用的函数放到这个结构体里:
- struct luaL_Reg xxx[] ={}
- 在动态库的入口函数里调用luaL_register将这个结构体注册
- 入口函数定义很重要,一定是要定义成
- int luaopen_XXX(lua_State *L) 否则就提示找不到动态库
- 在这个入口函数注册结构体时,要注册成:
- luaL_register(L,"XXX",lib),与入口函数的luaopen_XXX的XXX要一致
- 在写脚本的时候,使用require("XXX"),就是入口函数的luaopen_后面的XXX,注意大小写敏感
- 编译生成的动态库命令成XXX.so,对,同入口函数的luaopen_后面的XXX一致
- 绿色处务必一致
- 动态库要供LUA调用的function,其定义要符合:
demo.c
#include <stdio.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
static int add(lua_State* L)
{
int a,b,c;
a = lua_tonumber(L,1);
b = lua_tonumber(L,2);
c = a + b;
lua_pushnumber(L,c);
printf("test hello!!!\n");
return 1;
}
static const struct luaL_Reg m_array[]={
{"demoadd",add},
{NULL,NULL}
};
int luaopen_demolib(lua_State* L)
{
luaL_register(L,"demolib",m_array);
return 1;
}
gcc demo.c -fPIC -shared -odemolib.so
demo.lua
#!/bin/lua
demo=require("testlib")
c=demo.demoadd(10,20)
print("The result is ",c)
lua调用c++动态库
// testlib.cpp
#include <iostream>
#include "lua.hpp"
extern "C" int luaopen_testlib(lua_State *L);
using namespace std;
/* 定义C++的Average 函数 */
int average(lua_State *L)
{
int num = lua_gettop(L); //获取参数个数
double sum = 0;
double avg = 0;
for(int i = 1; i <= num; i++) //注意Lua栈下标从1开始
{
sum += lua_tonumber(L, i); //求和
}
avg = sum / num; //求平均
lua_pushnumber(L, avg); //平均值入栈
lua_pushnumber(L, sum); //和入栈
return 2; //return 返回值个数
}
/* 定义C++的sub函数 */
int sub(lua_State *L)
{
int num = lua_gettop(L);
if(num != 2)
{
cout << "Input param number is not correct!" << endl;
return 0;
}
int a = lua_tonumber(L, 1); //获取第一个参数,被减数
int b = lua_tonumber(L, 2); //获取第二个参数,减数
int diff = a - b;
lua_pushnumber(L, diff); //结果压入栈
return 1;
}
/* 定义C++的add函数 */
int add(lua_State *L)
{
int num = lua_gettop(L);
if(num != 2)
{
cout << "Input param number is not correct!" << endl;
return 0;
}
int a = lua_tonumber(L, 1); //获取第一个参数,被减数
int b = lua_tonumber(L, 2); //获取第二个参数,减数
int sum = a + b;
lua_pushnumber(L, sum); //结果压入栈
return 1;
}
//使用luaL_Reg注册新的C函数到Lua中
static luaL_Reg test_functions[] =
{
{"average", average},
{"add", add},
{"sub", sub},
{NULL, NULL} 数组中最后一对必须是{NULL, NULL},用来表示结束
};
/* luaopen_XXX,XXX为库名称,若库名称为testlib.so,XXX即为testlib */
int luaopen_testlib(lua_State *L)
{
luaL_newlib(L, test_functions); //Lua 5.2之后用luaL_newlib代替了luaL_register
return 1;
}
g++ -std=c++11 -shared -fPIC testlib.cpp -o testlib.so -I/usr/local/include -I. -L/usr/local/lib -llua -ldl
--lua call cpp function
local abc = require("testlib")
avg,sum = abc.average(100, 200, 300, 400, 500)
diff = abc.sub(100,50)
total = abc.add(100,50)
print("Average is:" ..avg)
print("Sum is: " ..sum)
print("diff = "..diff)
print("total = "..total)
浙公网安备 33010602011771号