[C++/Lua]开发Lua功能扩展DLL

来源:互联网 发布:软件测试思路 编辑:程序博客网 时间:2024/04/27 10:02

Lua库里面有一个函数package.loadlib,可以象LoadLibrary+GetProcAddress一样加载并获得DLL的导出函数地址,

package.loadlib (libname, funcname)

Dynamically links the host program with the C library libname. Inside this library, looks for a function funcname and returns this function as a C function. (So, funcname must follow the protocol (see lua_CFunction)).

This is a low-level function. It completely bypasses the package and module system. Unlike require, it does not perform any path searching and does not automatically adds extensions. libname must be the complete file name of the C library, including if necessary a path and extension. funcname must be the exact name exported by the C library (which may depend on the C compiler and linker used).

This function is not supported by ANSI C. As such, it is only available on some platforms (Windows, Linux, Mac OS X, Solaris, BSD, plus other Unix systems that support the dlfcn standard).

 

有了这个函数,我们可以非常方便地使用C++开发DLL来扩展Lua的功能,下面简单介绍下使用VS2008创建DLL的过程。

首先,打开VS2008,创建一个Visual C++的“Win32项目”,填写工程名称后确定,下一步,选择DLL(D),“导出符号”可以勾也可以不勾,在这里我们用def文件来导出DLL函数。

点击“完成”后,右键解决方案资源管理器的工程图标,添加->新建项,选择“模块定义文件”,文件名和工程名一样就可以了,点击确定。

在“工程名.cpp”里面添加以下代码(我这里的工程名是DLLForLua):

#include "stdafx.h"#include "DLLForLua.h"#define R(funcName) { #funcName, funcName }static int HelloWorld(lua_State* L){MessageBox(NULL, TEXT("Hello World!!!"), NULL, MB_OK);return 0;}static int Add(lua_State* L){if (lua_gettop(L) == 2) // 两个参数{if (!!lua_isnumber(L, 1) &&!!lua_isnumber(L, 2)) // 两个参数都是数字{int nAdd1, nAdd2;nAdd1 = (int)lua_tonumber(L, 1);nAdd2 = (int)lua_tonumber(L, 2);lua_pushinteger(L, nAdd1 + nAdd2);return 1; // 返回 1 表示返回 1 个参数}}lua_pushinteger(L, 0); // 发生错误return 1;}static const luaL_Reg regFuncs[] = {R(HelloWorld),R(Add),{ NULL, NULL }};__declspec(dllexport) int luaopen_DLLForLua(lua_State* L){//MessageBox(NULL, TEXT("Register C++ Functions..."), NULL, MB_OK);luaL_register(L, "DLLForLua", regFuncs);return 1;}


然后在“工程名.h”里面添加下面的代码:

#pragma once// 注意:一定要加上 extern "C"extern "C"{#include "inc/lua.h"#include "inc/lualib.h"#include "inc/lauxlib.h"};//#pragma comment(lib, "lua.lib")//#pragma comment(lib, "lualib.lib")#ifdef _DEBUG#pragma comment(lib, "lua51d.lib")#else#pragma comment(lib, "lua51.lib")#endif


在“工程名.def”里面添加:

LIBRARY"DLLForLua"EXPORTSluaopen_DLLForLua @1


好,点击“生成->生成解决方案”后就大功告成了!另外需要注意的是生成DLL要添加lua5.1的库文件和头文件的支持,这个我在后面的附件中会连同整个C++工程发给大家。

大家可以注意到在以上函数中只有luaopen_DLLForLua是导出函数,这个是为了给lua注册C++的函数用的,注册后lua脚本就可以调用C++写的函数了,这个函数里面luaL_register函数中,第二个参数是模块名,相当于lua里面的module函数,第三个参数是一个函数表结构数组,类似于"Lua函数名"<--->“C++函数指针”这样的表,用NULL, NULL来结束整个表结构。

最后把整个工程发给大家:http://download.csdn.net/detail/tzwsoho/4265447

另外还有个C++做的EXE和Lua互相调用的例子:http://download.csdn.net/detail/tzwsoho/4289449