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一致
    • 绿色处务必一致
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)

原文连接

posted on 2021-07-26 07:06  lodger47  阅读(463)  评论(0)    收藏  举报

导航