因为需要在windows下写一个测试客户端,之前用Lua写了一个,前天调试的时候出现了问题,找了很久才发现原来来自服务端的包可能是经过zlib进行压缩的,自然而然就需要在这个Lua的测试客户端中引入zlib的库了!
1.到http://luaforge.net/projects/luazlib/中下载已经写好的luazlib的接口文件;
2.到http://www.winimage.com/zLibDll/zlib125.zip下载windows下的zlib库,进行编译但是出现错误,在网上搜到了一个解决方法(以下内容为转载):
-----------------------------------------------------------------------------------------------------------------------
从zlib网站下载zlib源文件zip包(zlib1.2.5.zip)到本地的机器上(本人的机器是windowsXP操作系统,按缺省设置安装的VS2008pro),解压缩后保存在本地磁盘的某一目录(d:/zlib-1.2.5)。该目录下包括若干子目录和源文件,其中一个子目录(d:/zlib-1.2.5/win32)中有若干make文件,Makefile.msc是在windows环境下采用微软编译器(vc6.0、VS2008等)的make文件,列出了4种编译方法:
# Usage:
# nmake -f win32/Makefile.msc (standard build)
# nmake -f win32/Makefile.msc LOC=-DFOO (nonstandard build)
# nmake -f win32/Makefile.msc LOC="-DASMV -DASMINF" /
# OBJA="inffas32.obj match686.obj" (use ASM code, x86)
# nmake -f win32/Makefile.msc AS=ml64 LOC="-DASMV -DASMINF" /
# OBJA="inffasx64.obj gvmat64.obj inffas8664.c" (use ASM code, x64)
本人的机器是32位系统,没有尝试第4种编译方式,前3种中只有第3种采用汇编的代码编译可以成功,前2种在编译的链接(link)过程中出现错误:
link -nologo -debug -incremental:no -opt:ref -def:win32/zlib.def -dll -implib:zdll.lib -out:zlib1.dll -base:0x5A4C0000 adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj gzwrite.obj infback.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj zlib1.res
Creating library zdll.lib and object zdll.exp
infback.obj : error LNK2019: unresolved external symbol _inflate_fast referenced in function _inflateBack
inflate.obj : error LNK2001: unresolved external symbol _inflate_fast
zlib1.dll : fatal error LNK1120: 1 unresolved externals
查看Makefile.msc文件,可以发现在定义OBJS时没有包括inffast.obj。
......
OBJS = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj /
gzwrite.obj infback.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
OBJA =
# targets
all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) /
example.exe minigzip.exe example_d.exe minigzip_d.exe
$(STATICLIB): $(OBJS) $(OBJA)
$(AR) $(ARFLAGS) -out:$@ $(OBJS) $(OBJA)
......
infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h /
inffast.h inffixed.h
inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h /
inffast.h
inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h /
inffast.h inffixed.h
inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
......
在make文件的OBJS中加入inffast.obj(如下所示)后,make文件中所列的第1种和第2种编译方式均可成功。
OBJS = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj /
gzwrite.obj infback.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj /
inffast.obj
本人不清楚make文件会有这样的问题,也不清楚是有意设计还是bug。
另:需要从"Visual Studio 2008 Command Prompt"使用nmake命令,以使VS2008相关系统参数正确设置。
-----------------------------------------------------------------------------------------------------------------------
于是解决了以上问题,生成了相应的zlib的dll文件;
使用VC6.0跟进以下文章加入相关的库和文件,进行编译;
-----------------------------------------------------------------------------------------------------------------------
VC中使用DLL需要用到相应的lib文件和头文件,
编译时需要用到头文件,链接时用到lib文件,运行exe时用到dll。
添加头文件目录可以使用tools->options 中的directories下的include files进行添加
添加lib文件可以使用两种方法:
1、在TOOLS->OPTIONS->Directories->Library files,加入你的LIB文件所在的目录,然后在Project->setting->object->Object/Library Modules中加入你的LIB文件,如you.lib
2、在Project->Add to Project->Files中将你的LIB文件直接加入到工程中去
3.首先要使用该函数的地方加上该LIB的头文件,然后在project->setting->link->加上你的LIB文件的路径
DLL则是在运行exe时,与其放在同一目录下即可
没有.lib文件,VC也可以调用DLL中的函数。QA000325 "如何使程序不出现在任务列表中"就是一个使用LoadLibrary和GetProcAddress调用DLL中的函数的例子,当然这个办法比使用.lib麻烦。VB虽然可以不通过.lib调用DLL,但你所能调用的DLL非常受限制。如果没有.lib,你可以使用前面提到的方法,或者参考QA003675 "如何将dll翻译成*.lib文件使用"建立自己的.lib。
关于.lib的格式,可以参考MSDN Library中《Microsoft System Journal》1996年7月Matt Pietrek 的文章。
-----------------------------------------------------------------------------------------------------------------------
虽然最后成功生成了相应的供lua使用的zlib库文件,但是还是不能在lua中使用,lua中报错说:“找不到指定模块”,网上一搜又找来解决方法:
-----------------------------------------------------------------------------------------------------------------------
Lua 调用C写的动态库遇到的问题及解决
最近一个项目用lua5.1.4和c++联合开发。在开发的开始阶段遇到了一点问题,问题如下:
用命令行运行:lua test.lua
lua: error loading modules 'dllforlua' from file './dllforlua.dll':
找不到指定的程序。
因为是第一次使用,这个问题困扰了我好几天。经过多番测试,发现如下规律:
如果用require调用的时候,C动态库的文件名必须要与导出函数保持一致。
例如:动态库名字:testlua.dll,那么导出函数必须如下:
extern "C"
LUALIB_API int luaopen_testlua(lua_State *L) {
lua_register(L, "average", lua_average);
return 0;
}
另外一种解决方法,用package.loadlib(绝对路径.dll, "导出函数名")
然后调用这个导出函数
dllentry = package.loadlib("D://myprogram//Lua//firstC//Release//luatest.dll", "luaopen_suibian")
dllentry()
avg, sum = average(10, 20, 30, 40, 50)
print("The average is ", avg)
print("The sum is ", sum)
说明:luatest.dll是动态库的名字,luaopen_suibian是导出函数名,2者可以不一致。
建议用第一种方式。 ......
-----------------------------------------------------------------------------------------------------------------------
根据以上的方法作出相应的修改,还是不行,最后发现了一个叫brimworks-lua-zlib的luazlib库,里面有一个zlib.def的文件,才忽然想起使用库是需要这样的导出文件,加上再编译,就能成功在lua中使用了!