在Lua中调用C函数

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

内容简介: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函数》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

ActionScript 3.0 Cookbook

ActionScript 3.0 Cookbook

Joey Lott、Darron Schall、Keith Peters / Adobe Dev Library / 2006-10-11 / GBP 28.50

Well before Ajax and Microsoft's Windows Presentation Foundation hit the scene, Macromedia offered the first method for building web pages with the responsiveness and functionality of desktop programs......一起来看看 《ActionScript 3.0 Cookbook》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具