整整的花了一个下午的时候,才在lua中调用了动态链接库。比起其他脚本语言,lua的调用方式算是比较繁琐的,但是lua的编程思想非常的统一,即lua和C之间的传值都是通过栈进行的,目前为止我还没有深入的去了解这个“栈”,但是这并不妨碍去使用”栈“。

当我们在一个空的工程中写下几个C/C++的函数,然后把属性类型设置为“动态链接库”以后,编译虽然成功了,DLL也产生了,但是我们得到的DLL是一个没有价值的数据文件,它缺少export函数(通过dumpbin /exports xxx.dll 观察),我们的lua也无法使用它。为了把我们写好的函数export出去,必须在函数名前,返回类型之后加上__declspec(dllexport),比如:

int add(int a, int b)
{
    return a + b;
}
 
//要修改为--->>>
int __declspec(dllexport) add(int a , int b)
{
    return a + b;
}

这是你就可以用dumpbin看到我们的add了。不对??是的,也行你看到的不是add,而是@ILT#$%^add(@$%) (我随便写个大概),那么你的工程一定是C++工程。这样的DLL只能通过引导库(lib)来实现,LUA用不了。为了能建立lua可以使用的库,必须在导出函数的最前面加上extern "C" (不能是__stdcall),所以此时的函数变成了:
extern "C" int __declspec(dllexport) add(int a , int b)
{
    return a + b;
}
还有一种常用的方法也可以得到extern的效果,那就是建立def文件,例如:
LIBRARY  mylib  
DESCRIPTION "Just for test"  
VERSION 1.0
EXPORTS  
    add
有了def,你就不需要再每个函数前加上extern “C”了。记得要在属性/连接器/输入/模块定义文件中输入def的文件名称。我们这个动态链接库以及lua.exe必须动态的连接lua.dll (lua5.2.dll),而不能静态的链接,否则你会得到错误:

stack traceback :
      [C]:?
      [C]:in function 'require'
      test.lua:1:in main chunk
      [C]:?
有了上面的知识铺垫,我们可以进入下一个环节了——让lua调用DLL。下面代码可以生成一个DLL。

#include <Windows.h>
 
extern "C"{
#include <lua.h>
#include <lauxlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <lualib.h>
#include <math.h>
}
 
static int mysin (lua_State *L) 
{
    double d = luaL_checknumber(L, 1);
    lua_pushnumber(L, sin(d));
    return 1;
}
 
static int l_printf(lua_State *L)
{
    const char * pPattern = luaL_checkstring(L, 1);
    const char * str = luaL_checkstring(L, 2);
    lua_pushnumber(L, printf(pPattern, str));
    return 1;
}
 
static int l_MessageBox(lua_State *L)
{
    const char * sTitle = luaL_checkstring(L, 1);
    const char * sText = luaL_optstring(L, 2, "");
    MessageBox(NULL, sTitle, sText, 0);
    return 1;
}
 
static const struct luaL_Reg mylib[] = 
{
    {"mysin", mysin},
    {"printf", l_printf},
    {"messagebox", l_MessageBox},
    {NULL, NULL}
};
 
extern "C" int __declspec(dllexport) luaopen_mylib(lua_State *L)
{
    luaL_newlib(L, mylib);
    return 1;
}
上面的代码中,最后export出去的函数是luaopen_mylib,一定要注意:函数名luaopen_mylib表明了最后输出的dll名称必须为mylib.dll,而且大小写要一致,否则lua无论如何都找不到luaopen_mylib函数的。我们可以在lua脚本中这样使用。

mylib = require("mylib")
mylib.printf("Say: %s\n", "hello world")
msgbox = mylib.messagebox

msgbox("hello from luaopen_mylib")
另外,我要介绍一下另一种老方法。在DLL代码中添加:

extern "C" int  __declspec(dllexport) MyMessageBox(lua_State *L)
{
    const char * sText = luaL_checkstring(L, 1);
    const char * sTitle = luaL_checkstring(L, 2);
    return MessageBox(NULL, sText, sTitle, 0);;
}
你猜对了,我们要export另一个函数,然后我们可以在lua中这样用到:
pf = package.loadlib("mylib.dll","MyMessageBox")

print(pf)
pf("hello", "again")

这两种方法的效果是一致的,但是第一种方式是最新的,后面一种似乎有点out of date了。
————————————————
版权声明:本文为CSDN博主「语言观止」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/snlscript/article/details/16340653

在lua中调用DLL相关推荐

  1. 天马行空W:在C++中调用DLL中的函数

    1.dll的优点 代码复用是提高软件开发效率的重要途径.一般而言,只要某部分代码具有通用性,就可将它构造成相对独立的功能模块并在之后的项目中重复使用.比较常见的例子是各种应用程序框架,ATL.MFC等 ...

  2. 在C++中调用DLL中的函数

    1.dll的优点 代码复用是提高软件开发效率的重要途径.一般而言,只要某部分代码具有通用性,就可将它构造成相对独立的功能模块并在之后的项目中重复使用.比较常见的例子是各种应用程序框架,ATL.MFC等 ...

  3. dll放在unity哪个文件夹下_unity中调用dll文件总结

    unity中调用dll文件总结 根据收集的资料,对unity中调用dll文件进行总结,目前常用的两种,在给出vs中封装dll文件的步骤. 一.调用c#中的dll文件 1.1封装dll文件 首先新建一个 ...

  4. Lua中调用C/C++函数 (转)

    1.前言 上次偶说到从C/C++中调用Lua的函数, 然后就有朋友问从Lua中如何调用C/C++的 函数, 所以偶们这次就来说说这个问题. 首先偶们会在C++中建立一个函数, 然后 告知Lua有这个函 ...

  5. java中调用 dll 动态库的简洁方法 JNative

    Java中调用DLL方法,是通过JNI接口实现的,http://www.ibm.com/developerworks/cn/java/l-linux-jni/ 这里有详细的说明.大概是先用Java写一 ...

  6. java中调用dll文件的两种方法

    https://www.cnblogs.com/huozhong/p/5830485.html JNA地址:http://blog.csdn.net/shendl/article/details/35 ...

  7. dll找不到dll electron_如何在Electron中调用Dll

    如何在Electron中调用Dll 客户端有些硬件的接口需要调试,是在电脑上连了一些硬件的设备,比如打印机.扫描仪或者进行串口通信等等.单靠JS是完成不了了,我们决定通过把C++或者C#把这些功能打包 ...

  8. XLua源码学习:Lua中调用CS

    在使用lua代码开发的过程中,一个非常重要的部分是对C#代码的调用,接下来就结合源码分析理解它的实现: 在lua中,使用诸如以下代码便可以调用C#的代码: CS.UnityEngine.Debug.L ...

  9. VS2013 C#中调用DLL

    winform界面中,使用C#编程调用DLL过程记录: (1)什么是DLL 动态链接库英文为DLL,是Dynamic Link Library 的缩写形式,DLL 是一个包含可由多个程序同时使用的代码 ...

  10. 在C++中调用DLL中的函数(2)

    本文转自:http://blog.sina.com.cn/s/blog_53004b4901009h3b.html 应用程序使用DLL可以采用两种方式: 一种是隐式链接,另一种是显式链接.在使用DLL ...

最新文章

  1. 使用MATLAB实现的小算法练习1
  2. Java Web架构知识整理——记一次阿里面试经历
  3. java dump分析工具_java性能分析与常用工具
  4. Apriltag可用图片:TAG16H5
  5. [NOIP2009] 最优贸易 (最短路,分层图)
  6. 牛客 - 骚区间(线段树+思维)
  7. 读书笔记--互联网必读《长尾理论》作者克里斯.安德森
  8. linux搭建虚拟化平台报告,部署KVM虚拟化平台------搭建(示例代码)
  9. php静态数组变量初始化,为什么数组初始化时,赋值不能是常量?
  10. 2020中国直播电商生态白皮书
  11. linux操作系统命令及流程图,计算机操作系统与简单命令
  12. python策略模式包含角色_Python 之策略模式
  13. 传智播客-刘意-java深入浅出精华版学习笔记Day03
  14. 学习笔记-OS - Exploits
  15. 肝通宵写了三万字把SQL数据库的所有命令,函数,运算符讲得明明白白讲解,内容实在丰富,建议收藏+三连好评!
  16. 涉密计算机涉密存储设备或者改作其他用途的,将未经安全技术处理的退出使用的涉密计算机涉密存储设备或者改作其他用途的依法给予处分...
  17. 银行业务中台这么搞,新产品上线提速60%
  18. jbox弹窗_Ztree结合jbox实现弹窗树结构
  19. 如何永久关闭笔记本键盘
  20. luoguP4188 [USACO18JAN]Lifeguards S

热门文章

  1. (转)DevOps,就是开发吃掉运维?
  2. Rust: codewars的Bleatrix Trotter
  3. 独家:为了永不停机的计算服务 - 三月月刊
  4. 云智能时代,开源软件的演进历程
  5. 【优化求解】基于matlab差分进化算法求解函数极值问题【含Matlab源码 1199期】
  6. 【优化算法】蝗虫优化算法(GOA)【含Matlab源码 936期】
  7. 【优化算法】改进型的LMS算法【含Matlab源码 630期】
  8. 【人脸表情识别】基于matlab PCA+SVM人脸表情识别评分系统【含Matlab源码 593期】
  9. 【车间调度】基于matlab遗传算法求解多目标流水车间调度问题【含Matlab源码 443期】
  10. 【路径规划】基于matlab任意架次植保无人机作业路径规划【含Matlab源码 322期】