首页 > 编程语言 >#Lua:Lua调用C++生成的DLL库

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

时间:2022-09-24 20:36:21浏览次数:71  
标签:编译 lua cpp2dll C++ DLL Lua include

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 <Windows.h>
#include "lua.hpp"
#include <iostream>
#include <time.h>
#include <cmath>

// 函数示例:参数输入顺序
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++编写的动态链接库

标签:编译,lua,cpp2dll,C++,DLL,Lua,include
From: https://www.cnblogs.com/chetwin/p/16726404.html

相关文章

  • C/C++ 宏定义
     宏定义(无参宏定义和带参宏定义) 宏定义是比较常用的预处理指令,即使用“标识符”来表示“替换列表”中的内容。标识符称为宏名,在预处理过程中,预处理器会把源程序中所......
  • C++自学笔记
    在C++中定义Definition一个类的时候要用分别的.h和.cpp文件去定义这个类.h和.cpp成对出现类的声明declaration和函数原型放在头文件里(.h)定义这些函数的结构主体就要放......
  • 【代码片段】Qt6.2.4 C++ 替换文件内容
    参考https://blog.csdn.net/xi__q/article/details/55050120https://blog.csdn.net/kllo__/article/details/120176545https://blog.csdn.net/u013625961/article/deta......
  • C++自学笔记 面向对象程序设计OOP(Object Oriented Programming)
    什么是对象?Objects=Attributes+ServicesData:ThepropertiesorstatusOperations:thefuctionsC语言中定义的变量用来存储数据,所以它可以理解为是“对象”“......
  • 08(C++二级)
    1.宏定义:(1)宏名一般用大写(2)使用宏可提高程序的通用性和易读性,减少不一致性,减少输入错误和便于修改。例如:数组大小常用宏定义(3)预处理是在编译之前的处理,而编......
  • C C++结构体四种方式
    第一种语法表示struct结构体名称{    数据类型member1;    数据类型member2; }; #include<iostream>usingnamespacestd;structStudent{int......
  • C C++指针面试题零碎整理
    最基础的指针如下:inta;int*p=&a;答:p指向a的地址,&是取a的地址。*指的是指针中取内容的符号。2.str[]和str*的区别:charstr1[]="abc";charstr2[]="abc";c......
  • 「浙江理工大学ACM入队200题系列」问题 L: 零基础学C/C++52——计算数列和2/1,3/2,5/3,8/
    本题是浙江理工大学ACM入队200题第五套中的L题我们先来看一下这题的题面.题面题目描述有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13,……计算这个数列的前n项和。注意:C语言中......
  • c++ -- 做题思想
    二分思想:比较显然的就是求某一个确定的值,那么看看他是不是单调的,连续的.        其次就是,把问题通过二分来进行转化,之前的不好做,通过二分转化一......
  • UEC++ 多线程(一) FRunnable
    虚幻官方文档:https://docs.unrealengine.com/5.0/en-US/API/Runtime/Core/HAL/FRunnable/FRunnable“runnable”对象的接口。可运行对象是在任意线程上“运行”的对象......