• #Lua:Lua调用C++生成的DLL库


    Lua调用C++生成的DLL库

    本文参考了某大佬的博客,写得十分详细,推荐!!!

    需求:

    在之前的求解器中添加了Lua库,使得程序可以在Lua脚本中实现自定义函数功能,考虑到未来可能需要与第三方程序库进行耦合计算,现在想到可以借助Lua脚本,在脚本中调用第三方动态库,以实现其功能的扩展。接下来将要简要记录下Lua中调用第三方库的实现过程。

    编译Lua库

    在windows平台下,借助mingw编译器进行编译。

    首先需要去下载Lua源代码,这里下载的是最新的Lua5.4

    在安装路径下进行编译,源码中已经写好了Makefile,可以直接进行编译

    mingw32-make mingw
    mingw32-make install local
    

    在install目录下得到lua.exe,lua54.dll,liblua.a 等可执行文件,动态库与静态库

    C++编写DLL接口

    以下给出了一个示例,注释比较详细

    cpp2dll.cpp

    #include 
    #include "lua.hpp"
    #include 
    #include 
    #include 
    
    // 函数示例:参数输入顺序
    int Lua_printf(lua_State *L)
    {
        int n = lua_gettop(L); // 判断输入参数个数
        switch (n)
        {
        case 0:
            std::cout << "intput Para Number is 0" << std::endl;
            break;
        default:
            std::cout << "intput Para is " << n << std::endl;
            int a = 0;
            for (int i = 1; i <= n; ++i)
            {
                a = lua_tonumber(L, i); // 从栈底,向上依次读取数据
                std::cout << a << " ";
            }
            std::cout << std::endl;
            break;
        };
        return n; // 返回n个参数
    }
    
    int Lua_pow(lua_State *L)
    {
        int n = lua_gettop(L); // 判断输入参数个数
        if (n != 2)
        {
            std::cout << "intput Para Number is not 2" << std::endl;
            return -1;
        }
        double a, b, temp;
    
        a = lua_tonumber(L, 1);
        b = lua_tonumber(L, 2);
    
        int re = std::pow(a, b);
        std::cout << "a=" << a << "|b=" << b << "|re=" << re << std::endl;
        // lua_pushstring(L, "re="); // 将返回结果压入栈中
        lua_pushnumber(L, re); // 将返回结果压入栈中
        // return 2;
        return 1;
    }
    
    // 注册名称与函数的对应关系
    static const luaL_Reg name_and_func[]{
        {"printf", Lua_printf},
        {"pow", Lua_pow},
        {NULL, NULL}};
    
    // 注册函数:函数名称"luaopen_xxx",其中,xxx必须是dll的名称,即"xxx.dll"
    extern "C"
    {
        int __declspec(dllexport) luaopen_cpp2dll(lua_State *L)
        {
            printf("start luaopen_lib\n");
            luaL_newlib(L, name_and_func); // 创建一个新表,并将函数入栈
            printf("end luaopen_lib\n");
            return 1;
        }
    }
    

    编译DLL

    编译时需要链接到Lua生成的静态库,所以g++编译时需要指定lua头文件路径,以及静态库路径,编译命令如下

    g++ cpp2dll.cpp -O3 -o cpp2dll.dll -shared -fPIC -I ./lua54/include -L absolute/path/to/lua54/lib -llua54
    

    至此生成得Lua可以识别的动态链接库cpp2dll.dll

    Lua中调用DLL

    编写如下的Lua脚本

    test.lua

    local cpp2dll = require("cpp2dll")
    
    cpp2dll.printf()
    cpp2dll.printf(0,1,2,3)
    
    a=2
    b=10
    print(a,"^",b,"=",cpp2dll.pow(a,b))
    print(b,"^",a,"=",cpp2dll.pow(b,a))
    

    lua.exe 执行test.lua脚本

    得到如下输出

    cmd$ lua.exe test.lua
    start luaopen_lib
    end luaopen_lib
    intput Para Number is 0
    intput Para is 4
    0 1 2 3
    a=2|b=10|re=1024
    2       ^       10      =       1024.0
    a=10|b=2|re=100
    10      ^       2       =       100.0
    

    最后,在Lua脚本中成功调用C++编写的动态链接库

  • 相关阅读:
    黑马Java第10讲—继承和修饰符
    《IEEE Transactions on Robotics》发表!北京大学研究团队推出具有多种运动模态的软体两栖机器人
    sprignboot新依赖nacos,报错一直连接本地的localhost:8848解决
    vue 两种路由模式具体实现
    2核4G服务器支持多少用户同时在线访问?卡不卡?
    Android10之Video MediaCodec硬解码流程(二十七)
    shiro550反序列学习
    socket数据读写
    创维电视安装apk软件
    微机原理_9
  • 原文地址:https://www.cnblogs.com/chetwin/p/16726404.html