ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

VS2013下编译podofo 0.9.5 x86静态库:完整流程与踩坑指南

VS2013下编译podofo 0.9.5 x86静态库:完整流程与踩坑指南 简介Podofo 0.9.5的VS2013 x86编译库文件包面向需要在Windows平台进行PDF读取、解析与写入的C开发者。包内含完整头文件以及编译好的静态库与动态库共113个文件107个.h头文件涵盖PdfDocument、PdfPage等核心类声明另有2个.lib、2个.dll及2个.pdb调试文件压缩包仅6.74MB便于直接集成到VS2013工程中。已有316人学习下载。该包省去了自行配置zlib与freetype依赖、逐一排查编译链接错误的过程拿到后即可在项目中调用Podofo的API实现PDF元数据提取、页面渲染与文本操作等功能适合需要快速搭建PDF处理能力的中级C开发者。 做 Windows 下的 PDF 解析和生成C 圈子能选的开源库其实不多podofo 算是我用得比较顺手的一个。这次要说的 podofo-0.9.5-vs2013-x86 库简单讲就是把 podofo 0.9.5 这套源码用 Visual Studio 2013 编译成 32 位的静态/动态库。为什么专门聊这个组合因为老项目、旧工具链和新库之间往往隔着不少坑市面上现成的预编译包又多半是 x64 或者新 VS 版本想找个直接能用的 x86 版本并不容易。这篇文章就把我当时编译这套库的完整过程、踩过的坑和最后的调用验证方式原原本本捋一遍适合正在维护 VS2013 老工程、或者需要在 32 位 Windows 程序里集成 PDF 读写功能的同学参考。1. 为什么是 podofo 0.9.5 VS2013 x86 这个组合1.1 版本和工具链的选择逻辑podofo 是一个用 C 编写的开源 PDF 库支持解析、生成、编辑 PDF 文件也能处理字体嵌入、加密、表单填写这些相对高阶的操作。和 Poppler、PDFium 相比podofo 的定位更轻量接口也更符合“用 C 操作 PDF”的直觉不需要引入 COM 或者浏览器内核那套复杂依赖对于桌面端工具类软件来说非常合适。为什么偏偏是 0.9.5这个版本大概发布于 2016 年左右是 0.9 系列里比较稳定的一个。它后面 0.10.x 版本做了不少接口调整比如 PdfMemDocument 的构造方式、PdfPainter 的绘制流程都有变化老项目如果已经基于 0.9.x 写了大量业务代码升级到 0.10 的成本相当高。我当时的项目从 0.9.x 早期版本一路用到 0.9.5接口层面基本没有迁移负担源码编译也比新版更省事所以锁定了这个版本。VS2013 这个选择其实更多是被动接受。很多工业软件、MFC 程序、上位机系统的工程都是 VS2013 时代沉淀下来的用的平台工具集是 v120第三方库的二进制兼容性都得顺着这个工具集来。除非整条工具链全部升级否则单独把一个库升级到 VS2019/VS2022 编译反而会引入大量运行时冲突。所以在这种老工程里VS2013 不是一个“想不想用”的问题而是一个“必须用”的约束。x86 则是目标程序的硬性要求。很多客户现场还有 32 位 Windows 系统或者程序里夹杂了 32 位的 ActiveX 控件、老驱动整个进程必须编译成 x86。哪怕你开发机是 64 位系统编译出来的 x86 库也照样能在 64 位系统上跑所以 x86 并不意味着“落后”它只是保证了最大的兼容面。1.2 静态库还是动态库怎么选podofo 0.9.5 在 Windows 上用 CMake 构建时可以通过 PODOFO_BUILD_SHARED 和 PODOFO_BUILD_STATIC 两个开关分别控制生成动态库还是静态库。我个人建议如果是给内部项目用优先选静态库如果要发布 SDK 给第三方开发商才考虑动态库。静态库的好处是部署简单最终 exe 里直接包含了 podofo 的代码不需要额外分发 dll也不存在 dll 版本冲突的问题。缺点就是 exe 体积会大一些而且如果多个模块都静态链接了 podofo内存里会有多份库代码。动态库则反过来适合多人协作、模块化拆分但发布时要保证 podofo.dll、以及它依赖的第三方 dll 都跟着走少一个就运行不起来。我当时选择的是静态库并且把依赖库也一并编译成了静态版本这样整个程序拷到任何一台 Windows 机器上都能直接跑不需要在客户机器上安装一堆运行库。1.3 依赖库清单podofo 不是完全独立的它在不同功能上依赖一些第三方库编译前一定要心里有数依赖库用途是否必需zlibPDF 内部的 FlateDecode 压缩/解压必需freetype字体渲染、TrueType 字体解析解析含字体 PDF 时必需libjpegJPEG 图像解码可选项libpngPNG 图像解码可选项libtiffTIFF 图像解码可选项OpenSSLPDF 加密、数字签名可选项这里有个小技巧需要提前说明如果项目不需要 PDF 加密和签名功能编译 podofo 时可以完全不提供 OpenSSL这样能省掉一大块麻烦。因为 OpenSSL 在 Windows 上的编译本身就比较折腾版本还容易和 VS2013 不兼容。我当时直接关掉了 OpenSSL 相关选项加密相关接口就留空业务上完全够用。2. 编译前的准备工作2.1 VS2013 环境确认动手之前先确认 VS2013 装好并且能正常编译。打开 Visual Studio 2013 的命令行工具VS2013 x86 Native Tools Command Prompt敲一下cl看看能不能输出版本号。如果没有这个命令行工具说明安装时没勾选 C 组件需要重新运行安装程序补上。VS2013 对应的是Visual Studio 12.0默认安装在C:\Program Files (x86)\Microsoft Visual Studio 12.0。注意VS2013 这个点已经比较老了如果你操作系统是较新的 Windows 版本建议把兼容模式、更新补丁都打齐否则可能出现安装程序卡死或者编译时莫名崩溃的问题。如果 VS2013 实在卸载不掉或者装不上还可以考虑绿色版的 VS2013 编译环境但那属于偏方了不在这次讨论范围内。另外如果你的程序需要跑在 Windows XP 上编译时要把平台工具集改成v120_xp这个设置不在 podofo 这边而是在你最终引用 podofo 的应用程序工程里。podofo 本身编译成普通的 v120 即可运行时库保持一致就行。2.2 获取源码和依赖podofo 0.9.5 的源码可以从 GitHub 上 podofo/podofo 仓库拉取注意切到对应的 tag。0.9.5 对应的 tag 就是PODOFO_0_9_5或者类似命名拉代码的时候不要只拉 master 分支因为主干上的代码已经演进到 0.10 甚至更高版本接口完全不同。源码目录结构大概是这样的src/核心库源码test/单元测试tools/一些命令行工具cmake/CMake 辅助脚本CMakeLists.txt顶层构建脚本依赖库的处理是个关键点。对于 VS2013 这个老环境用 vcpkg 几乎行不通因为新版 vcpkg 要求 VS2015 以上用 conan 也不方便匹配老编译器。最稳妥的办法是自己编译一整套依赖库或者找同事/团队里沉淀好的老版本预编译包。如果你没有现成的我给一个省事思路把 zlib、freetype、libjpeg、libpng、libtiff 都下载对应版本的源码统一用 VS2013 编译成 Debug/Release 两个配置的静态库然后放到同一个目录里。搜这些依赖库源码的时候要注意不要从乱七八糟的下载站下载不明文件去各自官网或者 GitHub 官方仓库拉下载完校验一下文件指纹避免被人动过手脚。这个习惯在编译任何开源库时都适用。2.3 CMake 配置的关键选项podofo 0.9.5 使用 CMake 构建建议先装一个 3.10 到 3.16 之间的 CMake 版本。太老的 CMake 可能不认识某些选项太新的 CMake 对 VS2013 的支持也可能被移除或弱化所以卡在中间段最合适。生成工程文件时命令行方式是这样的cmake -G Visual Studio 12 2013 -DCMAKE_INSTALL_PREFIXD:/libs/podofo-0.9.5-install -DPODOFO_BUILD_SHAREDOFF -DPODOFO_BUILD_STATICON -DPODOFO_BUILD_LIB_ONLYON -DCMAKE_INCLUDE_PATHD:/libs/thirdparty/include -DCMAKE_LIBRARY_PATHD:/libs/thirdparty/lib ..几个关键参数分别解释一下-G Visual Studio 12 2013指定生成 VS2013 的工程这里 12 是 VS2013 的版本编号。新版 CMake 还可以加-A Win32显式声明 32 位老版本默认就是 Win32 平台不用画蛇添足。PODOFO_BUILD_SHAREDOFF和PODOFO_BUILD_STATICON只编译静态库不输出 dll。PODOFO_BUILD_LIB_ONLYON只构建 podofo 核心库不编译自带的命令行工具省时间也省去工具编译可能带来的问题。CMAKE_INCLUDE_PATH和CMAKE_LIBRARY_PATH指定依赖库的头文件和库文件搜索路径。如果你把第三方库也统一放到了某个目录这一步非常省事。如果依赖库路径分散也可以直接修改 CMakeLists.txt 里的相应find_path/find_library自定义路径的优先级最高。不过不建议改动源码构建脚本容易维护不了能用参数解决就尽量用参数。3. 编译实战从源码到可用的 lib 和 dll3.1 编译 podofo 的完整步骤整个流程我按实际操作的顺序走一遍。假设源码已经解压到D:/src/podofo-0.9.5依赖库头文件在D:/libs/thirdparty/include库文件在D:/libs/thirdparty/lib。第一步进入源码目录新建一个build目录避免源码目录里混入构建产物cd D:/src/podofo-0.9.5 mkdir build cd build第二步执行上面那段 CMake 命令。如果一切顺利build目录下会出现podofo.sln和一堆vcxproj文件。第三步编译。两种方式任选方式一用 CMake 的构建命令cmake --build . --config Release --target install方式二用 VS2013 命令行工具直接编译msbuild podofo.sln /p:ConfigurationRelease /p:PlatformWin32然后手动把生成的podofo.lib和头文件拷到目标目录。这里我建议用--target install它会按照 CMake 里的install规则把库、头文件、cmake 配置文件统一规整到CMAKE_INSTALL_PREFIX指定的目录目录结构清晰后面引用也方便。编译过程中如果一切顺利几分钟就能完成最终在D:/libs/podofo-0.9.5-install下会看到lib和include两个目录。include里是 podofo 的头文件lib里是podofo.libRelease 静态库Debug 版本则生成podofod.lib。3.2 配置 Debug 和 Release 的注意事项编译 podofo 本身只是第一步真正考验人的是把库接到你的项目里。这里最容易翻车的就是 Debug/Release 不匹配。podofo 0.9.5 的库文件名是有讲究的Release 版本叫podofo.libDebug 版本叫podofod.lib不要搞混。VS 工程里Debug 和 Release 配置需要分别指定对应的库文件同时要保证运行库设置一致。项目属性 - C/C - 代码生成 - 运行库Debug 通常用/MDdRelease 用/MD。podofo 编译时也要遵循同样的规则否则链接的时候会报大量LNK2038之类的不匹配错误要不就是运行时莫名其妙崩溃。为什么这个点重要因为运行库决定了程序链接哪个版本的 C/C 运行时库。Debug 版 podofo 用的运行库全名和 Release 不一样如果在 Release 工程里引用了 Debug 版 podofo.lib链接器会直接报错。这个问题在百度上搜出来的报错能堆一屏但绝大多数原因就是 Debug/Release 混用排查时先把这个检查掉。3.3 一个简单的调用实验库编译好后第一时间建一个最小的测试程序验证它能不能用。在 VS2013 里新建一个 Win32 控制台应用程序项目属性里做三件事附加包含目录D:/libs/podofo-0.9.5-install/include附加库目录D:/libs/podofo-0.9.5-install/lib附加依赖项Release 下填podofo.libDebug 下填podofod.lib然后写一段最简单的解析代码测试#include podofo/podofo.h #include iostream using namespace PoDoFo; int main() { try { PdfMemDocument doc; doc.Load(test.pdf); std::cout 页面数量: doc.GetPageCount() std::endl; for (int i 0; i doc.GetPageCount(); i) { PdfPage* page doc.GetPage(i); PdfRect rect page-GetRect(); std::cout 第 (i 1) 页尺寸: rect.GetWidth() x rect.GetHeight() std::endl; } } catch (const PdfError e) { std::cerr PDF 加载失败: e.what() std::endl; return -1; } return 0; }注意 include 语句是#include podofo/podofo.h不是#include podofo.h这个细节非常容易踩坑。很多人在编译 podofo 程序时报“找不到头文件”其实是因为头文件搜索路径没有加上或者 include 写法不对。如果程序能正确打印出 PDF 页数和页面尺寸说明整条链已经通了。再进一步测试 PDF 生成功能可以尝试用PdfStreamedDocument创建一个简单的 PDF 文件PdfStreamedDocument doc(output.pdf); PdfPage* page doc.CreatePage(PdfPage::CreateStandardPageSize(ePdfPageSize_A4)); PdfPainter painter; painter.SetPage(page); painter.DrawText(50, 50, Hello podofo); painter.FinishPage(); doc.Close();生成成功后用任意 PDF 阅读器打开output.pdf能看到一页 A4 纸上面有一行文字这就算完整验证了读写两端都没问题。4. 常见问题与排查技巧4.1 编译报错速查表编译 podofo 时遇到的报错大多集中在这么几个位置我整理成了一张速查表方便直接对照处理报错信息原因解决办法fatal error C1083: 无法打开包括文件 zlib.hzlib 头文件路径未配置检查 CMAKE_INCLUDE_PATH 或工程附加包含目录error LNK1104: 无法打开文件 zlib.lib链接器找不到 zlib 库确认 zlib.lib 是否在库搜索路径且版本是 32 位error LNK2038: 检测到 RuntimeLibrary 不匹配Debug/Release 运行库不一致将 podofo 工程与被调用工程的运行库设为一致error C2065: snprintf: 未声明的标识符VS2013 对 C99 函数支持不完整在源码或预处理器中定义_CRT_SECURE_NO_WARNINGS或自行封装替代函数error C4819: 该文件包含不能在当前代码页表示的字符源文件编码与系统代码页冲突在项目属性里关闭警告或统一将源码保存为 UTF-8 with BOM找不到 OpenSSL 头文件开启了加密功能但未提供 OpenSSL关闭 PODOFO_HAVE_OPENSSL 相关选项或者补齐 OpenSSL 依赖上面这些报错里C4819 最容易被忽略。podofo 0.9.5 的某些源文件自带非 ASCII 字符注释在中文 Windows 下编译时VS2013 经常报这个警告如果不处理后续可能出现奇怪的编译错误。直接在项目属性 - C/C - 命令行加一个/wd4819关闭这个警告即可不影响使用。4.2 链接时的经典坑链接 podofo.lib 时除了 Debug/Release 混用还有两个高频问题。第一32 位库和 64 位库混用。如果你试图在 x64 平台上链接 x86 的 podofo.libVS2013 会直接提示module machine type x86 conflicts with target machine type x64。这个报错很直白但很多人第一次遇到时并不清楚自己到底编的是哪个平台。检查思路是打开 Visual Studio 的配置管理器确认当前活动平台是 Win32 还是 x64再检查 podofo.lib 的实际位数。用 VS2013 自带工具dumpbin也能查看命令是dumpbin /headers D:/libs/podofo-0.9.5-install/lib/podofo.lib在输出里找到FILE HEADER VALUESmachine (x86)就是 32 位machine (x64)就是 64 位。第二回调依赖库的链接顺序。podofo 静态库本身并不包含 zlib、freetype 的代码链接你的可执行程序时还需要把 podofo 依赖的三方库也加到附加依赖项里。这个顺序挺重要把 podofo.lib 写在前面后面依次跟 zlib.lib、freetype.lib、libjpeg.lib、libpng.lib、libtiff.lib。如果顺序不对某些老版本链接器会报“无法解析的外部符号”调整一下顺序就好了。4.3 运行时的 DLL 问题和部署如果你编译的是动态库版本运行时就会牵扯到 DLL 分发问题。podofo.dll 依赖的 MSVCR120.dll 是 VS2013 的 C 运行时库目标机器如果没有安装 VS2013 Redistributable程序启动就会报“缺少 MSVCR120.dll”。解决方式是要么安装对应版本的 VC Redistributable要么在发布目录里带上这些 DLL。怎么查一个 exe 依赖哪些 DLL打开 VS2013 的命令行工具执行dumpbin /dependents your_app.exe输出里的DLL Name一栏会把所有依赖项列出来。看到podofo.dll再继续查podofo.dll的依赖项一层层追下去就能确定发布时要带哪些文件。这里要注意 x86 版本的程序必须带 x86 版本的运行库 DLLx64 同理不能混装。如果你最终选择了静态链接这些 DLL 问题基本可以绕过。但静态链接有个隐蔽的坑如果程序内部还用了其他动态库而那个动态库也是静态链接了 podofo 的那么两个模块各有一份 podofo 代码碰到全局状态比如加密模块的初始化时可能出现不可预料的干扰。不过对于一般应用场景这个概率很低不用过度担心。还有一点想单独提醒如果你编译库的时候开了加密功能运行时可能会依赖 OpenSSL 的 DLL。前面说了我直接关闭了 OpenSSL这步省了很多事。如果你的业务坚持要加密支持务必把 OpenSSL 的版本和 podofo 的接口匹配好否则加密 PDF 时容易出现崩溃或无法打开的问题。我个人实际操作下来最省心的策略就是固定一套 VS2013 32 位静态库 关闭 OpenSSL 的组合编译一次把 include、lib、依赖 DLL 全部归档到一个目录里整个团队共用这一套。后续有人需要重复编译时直接对照这篇流程走基本二十分钟能跑通。这个版本的 podofo 虽然老但稳定性和资料完善度都足够少折腾依赖版本才能把精力留在业务功能上。本文还有配套的精品资源点击获取
返回列表