在Lua中调用C函数

栏目: Lua · 发布时间: 5年前

内容简介:Lua调用C语言中的函数是通过栈来进行参数传递的,这与大部分编程语言的内部函数调用的实现一致。我们先实现如下C代码我们把上面的代码保存在

Lua调用 C语言 中的函数是通过栈来进行参数传递的,这与大部分编程语言的内部函数调用的实现一致。

我们先实现如下C代码

#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>

#include <stdio.h>
#include <sys/time.h>

static int i_add(lua_State * L)
{
    // 获取第一个函数参数
    double a = luaL_checknumber(L, 1);
    printf("第一个参数:%f\n", a);

    // 获取第二个函数参数
    double b = luaL_checknumber(L, 2);
    printf("第二个参数:%f\n", b);

    // 设置函数返回值
    lua_pushnumber(L, a + b);

    // 函数返回值的数量,在这里函数返回值为1
    return 1;
}

static int i_swap(lua_State * L)
{
    int i = lua_tointeger(L, 1);
    int j = lua_tointeger(L, 2);
    printf("%d 和 %d 交换位置\n", i, j);

    lua_pushinteger(L, j);
    lua_pushinteger(L, i);

    return 2;
}

// 计算斐波拉契数列
static int i_fib(lua_State * L)
{
    // lua_Integer长度为64位,防止溢出(事实上当n的值达到100左右即使64位也会发生溢出了)
    lua_Integer sum = 0;
    lua_Integer a = 0; // n - 2
    lua_Integer b = 0; // n - 1

    int n = lua_tointeger(L, 1);
    int i = 0;
    while (i <= n) {
        // printf("sum is %d\n", sum);
        i++;
        if (i == 1) {
            a = 0;
            b = 1;
        }
        sum = a + b;
        a = b;
        b = sum;
    }

    lua_pushinteger(L, sum);
    return 1;
}

// 获取当前的毫秒时间戳
static int i_time(lua_State * L)
{
    struct timeval tv;
    gettimeofday( &tv, NULL );
    double t = tv.tv_sec + (double)((int)(tv.tv_usec*0.001) * 0.001);

    // 以整数返回
    lua_pushinteger(L, (lua_Integer)(t * 1000));
    return 1;
}

// 打开名为mylib的库,在 Lua 中使用require('mylib')可以调用mylib中的函数
int luaopen_mylib(lua_State * L)
{
    // 对函数进行注册,之后在Lua中可以直接调用
    lua_register(L, "add", i_add);
    lua_register(L, "swap", i_swap);
    lua_register(L, "fib_c", i_fib);
    lua_register(L, "current_time", i_time);
    return 0;
}

我们把上面的代码保存在 mylib.c 文件中,随后使用如下命令对源代码进行编译得到 mylib.so 文件

gcc mylib.c -fPIC -shared -o mylib.so -I/usr/local/include/lua5.3 -llua5.3

得到动态链接库之后我们在当前文件夹下创建 test.lua 文件,之后输入如下代码

package.cpath = './?.so;' .. package.cpath -- 把库文件添加到环境变量中

require('mylib')
print(add(1, 2))
print(swap(2333, 666))

-- 计算斐波那契数列
fib_lua = function(n)
    sum = 0
    a = 0 -- n - 2
    b = 0 -- n - 1

    i = 0
    repeat
        i = i + 1
        if i == 1 then
            a = 0
            b = 1
        end
        sum = a + b
        a = b
        b = sum
    until i > n
    return sum
end

n = 10000000 -- 计算的斐波那契数列位数

-- 使用lua计算
start = current_time()
fib_lua(n)
luaCost = current_time() - start
print(luaCost)

-- 使用C语言计算
start = current_time()
fib_c(n)
cCost = current_time() - start
print(cCost)

-- 计算lua与C语言的耗时比
print(luaCost / cCost)

执行 lua test.lua 得到如下结果:

第一个参数:1.000000
第二个参数:2.000000
3.0
2333 和 666 交换位置
666     2333
1887
40
47.175

至此我们就使用Lua成功的调用了C语言中的函数,我们发现C语言的执行效率差不多是Lua的四十多倍(C语言的执行效率是 Python 的80多倍),可见Lua作为一个脚本语言,其执行速度还是很快的。


以上所述就是小编给大家介绍的《在Lua中调用C函数》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

STL源码剖析

STL源码剖析

侯捷 / 华中科技大学出版社 / 2002-6 / 68.00元

学习编程的人都知道,阅读、剖析名家代码乃是提高水平的捷径。源码之前,了无秘密。大师们的缜密思维、经验结晶、技术思路、独到风格,都原原本本体现在源码之中。 这本书所呈现的源码,使读者看到vector的实现、list的实现、heap的实现、deque的实现、Red Black tree的实现、hash table的实现、set/map的实现;看到各种算法(排序、查找、排列组合、数据移动与复制技术......一起来看看 《STL源码剖析》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具