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:Lua调用C++生成的DLL库的更多相关文章

  1. c++调用matlab生成的Dll动态连接库

    点击打开链接http://download.csdn.net/detail/nuptboyzhb/4228429 c++调用matlab生成的Dll动态连接库 实验平台:   matlab 7.0(R ...

  2. C++调用C#生成的DLL文件的各种问题

    C++调用C#生成的DLL文件: 首先选择建立一个C#的类库,然后再按照需求编写需要的函数 之后,对于C++调用过程需要注意的几点: 1.使用#using <....some.dll>指出 ...

  3. php调用C#生成的dll(二)

    根据上一篇博文,php调用c#生成的动态库,运行测试时报Fatal error: Class 'COM' not found in XXXXXXXXX 原因是php.ini中未开启COM组件的应用,解 ...

  4. 示例 - 如何在NodeJS中调用SS生成的DLL

    要想在NodeJS中调用SS生成的DLL, 需要借助EdgeJS. EdgeJS: http://tjanczuk.github.io/edge/ 如果你还不知道如何在SS中生成DLL, 请查看: S ...

  5. C#调用Matlab生成的Dll

    问题描述:最近开发需要调用matlab生成的DLL,在New MWNumericArray 对象的时候报错,提示未将对象引用到对象的实例. 问题分析:因为MWArray.dll是Matlab提供的DL ...

  6. Qt Creator调用VS2008生成的DLL注意事项 good

    问题:生成的dll文件QT无法静态/隐式调用 分析:调用的lib库可能是msvc编译的,而我用Qt调用,Qt默认编译器是minGW,两种编译器生成的函数名不一样,所以调用的时候你要用哪个函数,编译结果 ...

  7. WPF调用C++生成的dll文件(示例)

    注:笔者使用的VS版本为2019.1.打开VS2019,选择文件 -> 新建 -> 项目 2.选择项目 新建项目时选择C++“控制台应用”语言:C++平台:Windows项目类型:空项目 ...

  8. WPF开发的界面调用C++生成的dll文件

    以引用d1.dll为例. [生成d1.dll] 文件——新建——项目——Visual C++——Win32项目,选择DLL,点击Finish.在d1.cpp中添加代码 #include "s ...

  9. Java採用JNI调用VC++生成的dll(Java与C++交互)

    应项目需求,须要android调用java,java再调用C++实现android一个图片匹配的功能,我们作为java组须要和C++和Android进行交互.以下是java和C++採用JNI的方式进行 ...

随机推荐

  1. 并查集和kruskal最小生成树算法

    并查集 先定义 int f[10100];//定义祖先 之后初始化 for(int i=1;i<=n;++i) f[i]=i; //初始化 下面为并查集操作 int find(int x)//i ...

  2. salt stack学习笔记

    saltstack运行模式: local master/minion salt ssh saltstack三大功能 远程执行命令 配置管理(状态管理) 云管理 安装: master  salt-mas ...

  3. 云存储?不依赖三方服务自己也可以搞,利用Docker来搭建分布式文件系统FastDfs

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_78 对于文件存储来说,一般情况下简单的处理就是在Django配置文件中配置存储目录,按照规则对文件进行上传或者下载. 实际上,当文 ...

  4. 基于阿里云直播实现视频推流(ffmpeg)/拉流(Django2.0)以及在线视频直播播放(支持http/https)功能

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_146 由于5g网络的光速推广,视频业务又被推上了风口浪尖,在2019年初我们还在谈论照片,短视频等关键字,而进入2020年,我们津 ...

  5. Nginx Rewrite资源重定向

    # Rewrite功能配置 # Rewrite功能主要是实现了url重写 # 如:你输入www.jd123.com,你可以通过Rewrite让它重定向到www.jd.com # Rewrite的实现依 ...

  6. NC20273 [SCOI2009]粉刷匠

    题目链接 题目 题目描述 windy有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色. 每 ...

  7. host,nslookup,dig 工具安装

    DNS-测试工具 在centos7.9 中 安装bind后发现缺少,检测工具 工具包安装: 1 [root@server]# yum install -y bind-utils 安装后再次查询,发现已 ...

  8. HCNP Routing&Switching之端口安全

    前文我们了解了二层MAC安全相关话题和配置,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/16618201.html:今天我们来聊一聊mac安全的综合解决方案端 ...

  9. 【HTML】学习路径4-align对齐-标签属性

    每个标签都可以设置各种属性,比如可以给一个段落标签添加一个name的属性: <p name="段落标签1"> 这一节我们学习一个属性:align对齐标签 第一章:ali ...

  10. Java开发学习(二十七)----SpringMVC之Rest风格解析及快速开发

    一.REST简介 REST(Representational State Transfer),表现形式状态转换,它是一种软件架构风格 当我们想表示一个网络资源的时候,可以使用两种方式: 传统风格资源描 ...