zlib - 编译
zlib - 编译
概述
账单分析程序写完了, 处理excel时用到了libxlsxwriter.
看了一下libxlsxwriter主页, 有新版本. 想自己编译一个libxlsxwriter.
libxlsxwriter编译时, 用到了zlib.
尝试先编译zlib.
笔记
zlib主页 https://www.zlib.net/
当前版本1.3
源码库位置 zlib’s GitHub repository
库地址 : https://github.com/madler/zlib.git
将zlib工程迁出到本地
将git版本切换到1.3(官方发布的最新版)
编译win10 + vs2019的zlib版本
在工程中翻看官方说明
如果想用vs环境编译zlib, \contrib\vstudio\下有对应的工程.
去 http://www.winimage.com/zLibDll 看了编译好的zlib输出.
不是最新版本的zlibDLL, 还是自己编译1.3的zlibDLL好些
我本地装了vs2019, 那就用VS2019打开vc14里面的工程编译.
编译出x86/x64 + debug/release这4种组合的输出.
编译出来的DLL叫zlibwapi.dll
官方发布的DLL叫zlib1.dll.
如果第三方工程(e.g. libxlsxwriter) 需要DLL叫zlib1.dll, 那么改一下zlibvc.sln的输出名称就好.
测试编译出的zlibDLL
将zlibwapi.dll拷贝到\zlib\contrib\vstudio\vc14\x64\ZlibDllRelease
这里有官方提供的测试程序(随着zlibvc.sln一起编译出来的)
测试一下ZlibDll
如果zlibDll不在, 直接运行测试程序就会报错.
如果zlibDll存在, 就可以正常进行zlib操作.
自己新建一个vs2019工程来编译zlibDll
因为官方没有说明, 如何包含文件, 用啥编译选项. 只能参考 \zlib\contrib\vstudio\vc14zlibvc.sln 中的zlibvc工程.
zlibvc工程中, 没有DllMain(), 由编译器自动生成DllMainCRTStartup()和DllMain()实现.
创建一个DLL工程
工程名称为zlib1
将生成的空DLL工程编译一下, 看看生成的DllMain(). 可以看到和官方的DllMain不同.
尝试删掉DllMain()实现, 再编译和官方Dll基本相同.
这说明官方工程是没有DllMain()实现的, 用的都是编译器自动生成的DllMain().
在自己DLL工程下, 建立zlib目录, 将官方zlib根目录下的.h, .c 拷贝到自己新工程的zlib目录下.
将 原始工程的 \zlib\contrib\minizip\ 目录下的*.h, *.c 拷贝自己DLL工程下的\zlib\contrib\minizip下.
将原始工程 \zlib\contrib\vstudio\vc14下的zlib.rc, zlibvc.def 拷贝到自己DLL工程目录下的\zlib\contrib\vstudio\vc14
将自己DLL工程改为不使用预定义头文件pch.h
头文件包含目录为.\zlib
预定义宏(e.g. release x64 ), 将原来默认的删掉, 改为如下
_CRT_NONSTDC_NO_DEPRECATE
_CRT_SECURE_NO_DEPRECATE
_CRT_NONSTDC_NO_WARNINGS
ZLIB_WINAPI
WIN64
将自己工程中包含的miniunz.c移除, 因为这里面有个main().
看了官方工程, 人家没包含miniunz.c, 这个文件应该是一个工具或测试程序的实现.
将DLL模块定义文件指定到编译选项(如果不指定这个, 就没有导出函数!)
编译的其他选项用默认的就行(其他编译选项可以不动, 已经实验过了, 用默认的就行. 大部分的编译设置, 不一定要和旧工程一样.)
编译完后, 需要看到编译产生了zlib1.dll和zlib1.lib.
如果没有zlib1.lib, 有可能说明DLL没有导出函数.
将自己编译的zlib1.dll丢到 \zlib\contrib\vstudio\vc14\x64\ZlibDllRelease下, 改名为zlibwapi.dll, 运行 testzlibdll.exe OK.
这说明, 无论DLL叫什么名称, 只要里面提供的导出函数定义(函数类型(_stdcall, _cdecl), 返回值, 参数)一样, 将DLL改名为程序需要的DLL名称, 就可以让程序正常运行.
这样, 就说明, 如果自己要编译一个开源的DLL工程, 自己换个工程名称比较好, 等用在程序中时(程序包发布打包时), 再改成程序需要的DLL名字好一些. 不容易和官方工程看混肴.
备注
编译zlib1.dll时, 有个警告. 原版工程没有.
比对了一下, 是我多加了minizip.c, 去掉警告就没了.
加文件时, 如果比对这原版工程, 一个一个的加入, 很麻烦.
等编译时, 有警告再去比对原版工程比较方便.
只要0错误, 0警告就好.
备注
DLL编译出来后, 给程序包含用的.lib, 指定了要使用的DLL名称.
这个存根.lib改名字是没用的, 等程序编译完成, 运行时, 是需要这个存根DLL中记录的对应的DLL的一个确定名称.
反之, 需要的DLL是可以根据exe调用DLL的要求去改名. 这样我们自己做一个程序要求的DLL, 只要DLL名称一样, 函数类型一样, 函数参数一样就可以正常运行.
看存根DLL的具体函数, 可以看到, 是根据一个指定的DLL名称+偏移去访问函数的. 改存根.lib的名字给exe工程是没用的.
在DLL工程中包含的模块定义文件中, 并没有指定.lib的名称. DLL工程编译完, 由编译器自动在存根.lib中加了具体要使用的DLL名称.
END
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!