C与Lua交互——在C和Lua之间相互传递数据

        C与Lua交互

                    ——在C和Lua之间相互传递数据,并以此操作SQlite3数据库


        使用Lua来操作Sqlite3数据库的过程,相比直接在C/C++下操作,简单得多。在嵌入式开发过程中,使用Sqlite3来管理系统中的大量数据,是一种非常成熟的做法;将Lua 和Sqlite3结合起来的开源技术Lua Sqlite3,就显得非常适合快速开发。

        这篇文章就是根据在项目开发过程中,提炼出来的实际经验总结。主要涉及到的技术知识背景有:

        1、Lua

        2、Sqlite3

        3、Lua Sqlite3 

        前面两点,网络资源非常丰富。第3点,网上的资源相比较少,主要就是官网的文档。

        本篇博客主要内容有:

        1、C/C++如何给Lua 函数传递参数?

        2、Lua如何给C/C++返回多个值?

        3、C/C++如何通过Lua 提供的接口访问Sqlite3 数据库?

        下面详细讲解:

        一、C/C++如何给Lua传递参数(传递多个参数)

        1、首先我们写一个lua脚本,脚本中提供了一个lua函数。保存为test.lua:

        

function set_data(...)
	local args = {...}
	for i=1,#args do
		print(args[i])
	end
end

        2、使用C++写一个测试程序,代码如下:

        

#include "lua.hpp"
#include 
using namespace::std;

lua_State* g_L = NULL;

bool initlua()
{
    g_L = luaL_newstate();//创建Lua栈

    lua_checkstack(g_L,60);//修改Lua栈大小为60,防止在C和Lua之间传递大数据时,崩溃

    luaL_openlibs(g_L);//运行Lua虚拟机

    int ret;
    if(ret=luaL_loadfile(g_L,"test.lua"))//装载lua脚本
    {
        cout<<"load test.lua fail."<

        编译上面的CPP文件时,须链接lua的库 -llua -ldl 

        运行结果如下:

        

# ./lua-c-example 
load test.lua ok
run test.lua ok
11
22
33
44
55
66
77
88
99
100

        二、Lua函数如何给C/C++返回多个值

        1、lua脚本内容如下,保存为test.lua:

    

local array = {1,2,4,5,6,7,8,9,10}

function get_data()
	print("get_data")
	return array	
end

        2、C++调用Lua函数,获取多个返回值的测试程序代码:

#include "lua.hpp"
#include 
using namespace::std;

lua_State* g_L = NULL;

bool initlua()
{
    g_L = luaL_newstate();

    lua_checkstack(g_L,60);

    luaL_openlibs(g_L);

    int ret;
    if(ret=luaL_loadfile(g_L,"test.lua"))
    {
        cout<<"load test.lua fail."<nil 入栈作为初始 key

    if(lua_isnil(g_L, index))//栈顶内容为空
    {
       return ;
    }
    while(lua_next(g_L, index))//循环遍历栈中内容
    {
        cout<

       运行结果如下:

# ./lua-c-example 
load test.lua ok
run test.lua ok
get_data
1 2 4 5 6 7 8 9 10    

        三、C/C++通过Lua 提供的接口访问Sqlite3 数据库

        结合一、二的讲解,应该很容易从C/C++端,通过lua提供的函数接口,访问sqlite3数据库。

        1、Lua创建数据库和表的脚本如下:

        

local sqlite3 = require("lsqlite3") --加载 Lua Sqlite3 库

local mydb = sqlite3.open("test.db") --打开/或者创建test.db数据库

mydb:exec[[ 
	CREATE TABLE main (
	ID INTEGER PRIMARY KEY AUTOINCREMENT, 
	year INTEGER, 
	month INTEGER, 
	day INTEGER, 
	hour INTEGER, 
	minite INTEGER, 
	second INTEGER);]]

        2、数据插入操作,使用lua sqlite3的statement语句,以提高插入大量数据时的效率:

main_stmt = mydb:prepare[[
	INSERT INTO main VALUES (
	?, ?, ?, ?, ?, ?, ?);	
	]] --7 values 申明一个插入操作的statement

        如下Lua函数为提供给C的数据库插入接口函数:

function insert_main(...)
  local args = {...}
  main_stmt:bind_values(nil,args[1],args[2],args[3],args[4],args[5],args[6])
  main_stmt:step()
  main_stmt:reset()
  return 9
end --提供一个供C/C++调用的Lua函数 insert_main。此函数为数据插入接口。

        3、数据查询操作,使用lua sqlite3的statement语句,以提高频繁查询时的效率:

select_stmt_main = mydb:prepare("SELECT * FROM main;")

        如下Lua函数为提供给C的数据库查询接口函数:

function select_main()
	local stepret = select_stmt_main:step()
	if stepret == sqlite3.ROW then
		local ret = select_stmt_main:get_values() --返回的是一个lua array
		return ret
	else
		select_stmt_main:reset() --重置statement,以便下一次从表头开始查询
		return nil
	end
end
        以上操作Sqlite3数据库的Lua脚本保存到一个文件db.lua中。结合前面的一、二提供的测试代码,很容易就达到了我们的目的——C/C++通过Lua 提供的接口访问Sqlite3 数据库。


你可能感兴趣的:(源码,嵌入式Linux)