将动态库导入到lua中
一、首先学习如何生成动态库
1.关键字__declspec dllexport可以导出数据、函数、类或类的成员函数。
2.vs2005新建Win32工程,选择DLL
new->Win32 Console Application->DLL(Application type)
3.网上的例子:
//DLL.cpp
#include <stdio.h>
extern "C" //一定记得要加××××××××
__declspec(dllexport) int function(char* aa,int bb )
{
printf("/nIn Function of the exported function./n");
printf("%s/t%d/n",aa,bb);
return 1;
}
class DLLClass
{
public:
__declspec(dllexport) void functionA(void)
{
printf("/nIn Function A of the exported function./n");
}
};
class __declspec(dllexport) ExportDLLClass
{
public:
void functionB(void)
{
printf("/nIn Function B of the exported class.");
}
};
__declspec(dllexport) DLLClass test;
运行后生成DLL.
下面是一般的生成exe文件的Win32工程中需要添加的代码:
//CallDLL.cpp
#include <stdio.h>
extern "C"
class DLLClass
{
public:
__declspec(dllimport) void functionA(void);
};
class __declspec(dllimport) ExportDLLClass
{
public:
void functionB(void);
};
__declspec(dllimport) DLLClass test;
int _tmain(int argc, _TCHAR* argv[])
{
ExportDLLClass TestClass;
test.functionA();
TestClass.functionB();
return 0;
}
__declspec(dllimport) int ClientToServer(char * serverIP,int portNum,char *sendMsg);
在属性的设置中,将DLL.cpp生成的动态dll和静态lib库添加进去,一般只添加静态库和路径即可,dll文件放debug文件夹中。
二、那么lua要导入的动态库有哪些要求呢?
1.lua5.1中的函数package.loadlib("dllname.dll","functionname")用来导入动态库中的函数,但是它要求的函数是lua_CFunction,且似乎只能是这个格式。就当是lua对dll导入的限制吧。
那么如何生成lua能读取的dll文件呢?
__declspec(dllexport) int function(char* aa,int bb )
{
printf("/nThe exported function./n");
printf("%s/t%d/n",aa,bb);
return 1;
}
这个是c++需要的导出函数的形式,但是lua能识别的只能是 int lua_CFunction(lua_State *L)的形式,
因此,我们需要添加另一导出函数,这样该函数在lua中导入后能传递参数。
__declspec(dllexport) int l_function(lua_State *L)
{
char * a = (char *)luaL_checkstring(L,1); //函数需要的第一个参数
int b = (int)luaL_checknumber(L,2); //函数需要的第二个参数
lua_pushnumber(L,function(a,b));
return 1; //返回结果个数
}
2.生成dll文件后,放到lua脚本相同路径中。若不在同一路径,则需要在loadlib的第一个参数中写明详细路径。
--calldll.lua
getdll = package.loadlib("DLL.dll","?function@@YAHPAUlua_State@@@Z")
--原型应该是package.loadlib("DLL.dll","function"),
--但是由于解释器无法识别函数名,因此只能通过DEPENDS.EXE读取dll文件来解析函数名后,写入lua脚本中
function func()
getdll("test!",5)
end
在lua5.1的解释器中执行该函数即可。
三、需要注意的问题
1. extern "C",少了这个会造成DLL生成不正确;
2. 可以先建立c++工程来测试相应的dll,保证正确性,避免lua解释器崩溃;
3. 函数名解析的问题,要通过工具DEPENDS.EXE,这个问题待解决;
4. 带有参数的函数需要建立int lua_CFunction(lua_State *L)的函数,分别导入各参数和函数。
有待更深入的研究。。。。。。
<补充>:函数名的解析问题
getdll = package.loadlib("DLL.dll","?function@@YAHPAUlua_State@@@Z")
--原型应该是package.loadlib("DLL.dll","function"),
lua脚本似乎没有办法去解析属于类或者lua_CFunction的函数,我们也可以通过DEPENDS.EXE看到,这些函数名显示的时候都加了一些其他固定格式的符号,但是导入lua中的时候脚本却无法去分析单纯的函数名。
解决:添加一个.def文件到c++工程里面,如下:
LIBRARY test.dll
EXPORTS
function @1
.......
.def文件具体的建立和格式MSDN里面有相应的说明,不多说了,反正是可以解决这个问题,亲身证实,hoho。