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. Java开发学习(十七)----AOP案例之测量业务层接口执行效率

    一.需求分析 这个需求比较简单 需求:任意业务层接口执行均可显示其执行效率(执行时长) 这个的目的是查看每个业务层执行的时间,这样就可以监控出哪个业务比较耗时,将其查找出来方便优化. 具体实现的思路: ...

  2. 虚拟机上安装Linux系统

    1,打开VMware,文件--新建虚拟机 2,选择自定义 3,选择VMware版本,下一步 4,选择稍后安装操作系统,下一步 5,选择Linux,版本我这里用的是centos7 6, 设置虚拟名称,设 ...

  3. 如何应对外包公司(文思海辉)的Python后端面试

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_151 最近春招如火如荼,我接触到的几位同学也纷纷去市场里试了试水,不得不说由于疫情的影响,导致目前中等水平的开发者择业有了些许困难 ...

  4. MySQL主从复制之GTID模式介绍

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. GTID概述 MySQL5.6 在原有主从复制的基础上增加了一个新的复制方式,即基于GTID的复制方式,它由UUID和事务 ...

  5. 051_末晨曦Vue技术_处理边界情况之provide和inject依赖注入

    provide和inject依赖注入 点击打开视频讲解更详细 在此之前,在我们描述访问父级组件实例的时候,展示过一个类似这样的例子: <google-map> <google-map ...

  6. Hadoop集群搭建的详细过程

    Hadoop集群搭建 一.准备 三台虚拟机:master01,node1,node2 时间同步 1.date命令查看三台虚拟机时间是否一致 2.不一致时间同步:ntpdate ntp.aliyun.c ...

  7. 以太坊 layer2: optimism 源码学习(二) 提现原理

    作者:林冠宏 / 指尖下的幽灵.转载者,请: 务必标明出处. 掘金:https://juejin.im/user/1785262612681997 博客:http://www.cnblogs.com/ ...

  8. 第六十六篇:Vue的watch侦听器

    好家伙,哇吃侦听器 1.watch侦听器 watch侦听器允许开发者监视数据的变化,从而针对数据的变化做特定的操作 1.1.侦听器的基本用法 <body> <div id=" ...

  9. 配置Windows server dhcp与AD域对接并使用Win1创的用户登录Win2

    创建两台windows_server_2012 创建步骤链接(https://www.cnblogs.com/zhengyan6/p/16338084.html) 注意:所有虚拟机都要在同意网段 配置 ...

  10. 使用man手册查看内核函数

    1.为避免man的一些功能缺失,先装好manpages-dev sudo apt-get install manpages-dev 2.安装mandocs的依赖包xmlto sudo apt-get ...