Lua中调用的dll文件的编写方法

前置说明

1.注意:如果你使用VS来编译DLL文件,那么请添加.def文件来说明dll的输出内容,否则Lua将无法调用你所编写的DLL。
2.如果你既不知道什么是.def(模块定义文件)也不知道如何编写dll文件,那么请看这篇博客,记得给博主点赞。。
http://www.blogjava.net/wxb_nudt/archive/2007/09/11/144371.html – DLL编写教程
3.请确保您知道什么是Lua库(lua.h,laulib.h,lualib.h等),并能够在编写代码的时候正确的使用它们。否则,请百度“lua解释器的编译”,它会让你了解Lua库,或者一步到位:购买一本《Lua程序设计》。唔,如果你能买到正版,请联系我 :P
4.请确保用C编译器来编译dll,如果非要用C++编写dll也可,但请加 extern “C”语句。至于为什么,请百度“extern C dll “

C API说明

编写给Lua调用的dll的必要C API,它们都包含在Lua库中

1.lua_register(#1,#2,#3) –>这是一个宏,用于向Lua中注册一个函数,该函数的名由#2参数决定。
#1:lua_state指针。(不知道请百度)
#2:字符串,决定在lua中该函数的名
#3:函数指针,指向被调用的C函数

2.luaL_register(#1,#2,#3) –> 同样是一个宏,用于向Lua中注册一个table,该table的名由#2参数决定。
#1 :lua_state指针。
#2:字符串,决定在lua中该table的名
#3:luaL_Reg数据结构数组

3.luaL_Reg – > 这是一个数据结构,通常要以数组的形式供luaL_register宏调用
结构为:
{#1,#2}
#1:字符串,表示函数的名
#2:函数指针
注:看到示例你会明白这个结构的作用的

关键:注册函数

每个供给Lua调用的dll的文件都不可少的需要一个函数,它的名是这样的:
luaopen_<模块名>
比如模块名叫 “math.dll”,那么注册函数就必须为 ”luaopen_math ”
注册函数的作用就是把供给lua调用的函数通通放入lua栈中,供lua调用

示例

这个示例用来展示dll的编写

C/C++ code

#include "windows.h"
#ifdef _cplusplus  
extern "C"{
#endif
#include 
#include 
#include 

    static int isquare(lua_State* L);//次方函数
    static int alert(lua_State* L);//警告函数,它从lua接受一个字符串参数,并以弹窗的方式显示出来
#ifdef ——cplusplus
}
#endif

static const struct luaL_Reg funcs[] = {
    { "isquare",isquare },
    { "alert",alert },
    {NULL,NULL}
};//这就是luaL_Reg的用法,它给c函数一个供lua调用的名,在lua中你就可以通过该名调用该c函数

int luaopen_func(lua_State* L){//这个就是注册函数
    luaL_register(L,"func",funcs);//func就是lua中table的名
    return 0;
}

static int alert(lua_State *L)
{
    const char * desc = lua_tostring(L, -1);
    MessageBox(NULL, desc, "alert", MB_OK);
    return 1;
}

static int isquare(lua_State *L){              /* C中的函数名 */
    float rtrn = lua_tonumber(L, -1);      /* 从Lua虚拟机里取出一个变量,这个变量是number类型的 */
    //printf("Top of square(), nbr=%f\n",rtrn);
    lua_pushnumber(L, rtrn*rtrn);           /* 将返回值压回Lua虚拟机的栈中 */
    return 1;                              /* 这个返回值告诉lua虚拟机,我们往栈里放入了多少个返回值 */
}

.def 文件

; export.def
LIBRARY FUNC
; MY_DLLMAIN 将成为生成的dll的名称
DESCRIPTION  'AllenPocket test'
EXPORTS
    isquare  @ 1
    alert    @ 2
    luaopen_func @3
; 这个名称即为函数的实际导出名称 @1为函数的导出编号

如果你不知道.def该如何在VS中配置,请百度

lua code

package.cpath = --匹配模式,请确保您的dll能在匹配模式中匹配到

require "func"

print(func.isquare(50))

func.alert("Hello World")

最后如果完全正确,结果就是:
2500

并有一个弹窗(只有在windows系统上才有该弹窗,因为我调了window.h库)
Lua中调用的dll文件的编写方法_第1张图片

你可能感兴趣的:(Lua学习)