随笔 - 8  文章 - 0  评论 - 0  阅读 - 2062

lua疑难问题记录

一、C语言调用Lua

-- func.lua
function func(str)
    print(str)
    return "Lua Progran"
end

 

复制代码
// test.c
#include <stdio.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>

const char* load_func(lua_State *L) {
    lua_getglobal(L, "func"); // 将func压到栈顶
    lua_pushstring(L, "C Program"); // 将字符串压入栈顶传递给Lua
    lua_pcall(L, 1, 1, 0); // 调用函数,预期有1个参数传递,返回1个值,使用标准错误处理方式
    const char* str = lua_tostring(L, -1); // 将栈顶元素转换为字符串类型
    lua_pop(L, 1); // 弹出栈顶1个元素
    return str;
}

int main() {
    lua_State *L = luaL_newstate();
    luaL_openlibs(L);
    luaL_dofile(L, "func.lua"); // 加载(lua_loadfile)和运行(lua_pcall)Lua脚本

    const char* str = load_func(L);
    printf("%s\n", str);

    lua_close(L);
    return 0;
}
复制代码

 

编译命令:

gcc -o test test.c -ldl -llua -lm

 

运行结果:

>$ lua func.lua
C Program Lua Progran

 

二、Lua调用C库

-- func.lua
package.cpath = package.cpath .. ";./?.so"

require("main") -- 加载main.so库,库的入口函数名为luaopen_main

local res = reduction(10, 7)
print(res)

 

复制代码
// test.c
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>

static int func(lua_State *L) {
    int x = luaL_checkinteger(L, 1); // 检测第1个参数是整数
    int y = luaL_checkinteger(L, 2); // 检测第2个参数是整数
    lua_pushinteger(L, x - y);
    return 1; -- 返回1个值
}

int luaopen_main(lua_State *L) {
    lua_register(L, "reduction", func); // 将函数func使用'reduction'名称注册进Lua库中
    return 0;
}
复制代码

 

编译命令:

gcc -fPIC -shared -o main.so test.c

 

运行Lua脚本结果:

>$ lua func.lua
3

 

三、使用中间层让Lua调用三方库

// 3rdparty.c
#include <stdio.h>

const char* show(const char* str) {
    printf("%s\n", str);
    return "3rdparty";
}

 

复制代码
// 3rdstub.c
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include <dlfcn.h>
#include <stdio.h>
#include <assert.h>

void loadlib() {
    void* handle = dlopen("./lib3rdparty.so", RTLD_LAZY);
    assert(handle != NULL);

    const char* (*f)(const char*) = 
            (const char* (*)(const char*))dlsym(handle, "show");
    assert(f != NULL);

    printf("%s\n", f("Stub Program"));

    dlclose(handle);
}

static int func(lua_State *L) {
    const char* s = luaL_checkstring(L, 1);

    loadlib();
    printf("%s\n", s);

    return 0;
}

int luaopen_3rdstub(lua_State *L) {
    lua_register(L, "stub", func);
    return 0;
}
复制代码

 

-- 3rdbody.lua
package.cpath = "./3rdstub.so"

require("3rdstub")

stub("Lua Program")

 

编译命令:

gcc -fPIC -shared -o lib3rdparty.so 3rdparty.c
gcc -fPIC -shared -o 3rdstub.so 3rdstub.c

 

运行Lua结果:

>$ lua 3rdbody.lua 
Stub Program
3rdparty
Lua Program

 

1、使用了require导入了c编写的lua库后,是否导入了这个库中所有使用lua_register注册了的函数?

    答:是的。

2、如果多个库中存在同名函数会出现什么情况?

    答:lua会根据使用require加载模块的次序覆盖之前的同名函数

3、Lua能够调用没有实现Lua API的动态库么?

    答:不能,因为数据结构、函数调用方式和内存管理需要使用Lua实现的。

4、我需要调用其他动态库有办法么?

    答:可以通过实现一个Lua API动态库作为中间层,完成Lua与其他动态库之间的数据交换。Lua  ->  Lua API动态库(中间层)  ->  其他动态库

 

posted on   TN-mo  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示