【原】lua个人学习记录(3)--导入动态库

【原】lua个人学习记录(3)--导入动态库
2007-08-10 00:31

将动态库导入到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。


类别:Lua | 添加到搜藏 | 浏览( 131) | 评论 (0)
 
上一篇: [转载]VC 常用快捷键    下一篇: lua_Tinker,这个还不错
 

你可能感兴趣的:(【原】lua个人学习记录(3)--导入动态库)