PDF开源库libharu的折腾之旅
最近入手了一台Kindle,想在上面看代码.发现直接放上去看不了。
好吧,就准备写个批量将代码文件自动转成带目录标签的PDF文件的程序。
找到了libharu这个开源库,准备开用,没想到要用起来真不容易。
下面是折腾记录。
开发环境: VS Express 2015 版本
相关工程下载
从github下载libharu
https://github.com/libharu/libharu
下载zlib
http://www.zlib.net/
下载libpng
http://libmng.com/pub/png/libpng.html
编译 zlib
cd zlib\contrib\vstudio\vc11
打开VS 工程,选择zlibvc编译
编译出64位 zlibwapi.lib与zlibwapi.dll
编译libpng
cd lpng1618\projects\vstudio
用VS 打开 vstudio.sln
libpng需要zlib的支持,使用我们刚编译好的zlib.
1. 在解决方案的属性页中,将libpng依赖zlib的勾拿掉
2. 在工程属性中设置好 zlib头文件及zlibwapi.lib和目录
编译得到 libpng16.lib及libpng16.dll
开始编译libharu
按 https://github.com/libharu/libharu/wiki/Installation#Windows_except_cygwinMSYS 中的说明来做:
cd libharu\script
更改Makefile.msvc和Makefile.msvc_dll
分别将 PNG_PREFIX 与 ZLIB_PREFIX 路径指向真实的libpng和zlib头文件所在目录.
及LDFLAGS行中将libpng13.lib更改为libpng16.lib.
然后运行编译命令
nmake -f script/Makefile.msvc
nmake -f script/Makefile.msvc_dll
会报 libhpdf.def : error LNK2001: 无法解析的外部符号 HPDF_3DAnnot_Set3DView
在def中去掉,然后发现是按win32方式写的编译脚本,修改成win64方式无果后。
果断用vs新建了一个libharu的vs新工程
libharu的vs 64位新工程:
1. 将libharu\src下所有.c 文件复制至工程目录
2. 将libharu\include目录下所有.h文件复制至工程目录
3.将libharu\win32\include目录下hpdf_config.h文件复制至工程目录
4.将zlib及libpng所有的.h文件分别建立include目录,并在工程中设定.
5.将zlib和libpng编译后的lib和dll文件建立lib目录,并在工程中设定.
6.将工程属性由默认的exe改为dll
7.在工程目录新建libhpdf.def文件,否则不会生成.lib文件
8.在链接器->输入->模块定义文件中输入libhpdf.def文件名,
如不输入可以在编译完成后用 lib /def:libhpdf.def 命令从dll生成.lib文件
编译完成即可得到LIBHPDF.lib和LIBHPDF.dll.
libharu终于编译完了,然后折腾又来了.
写了个例子测试,编译时发现一堆 declared deprecated 类错误。 #pragma warning (disable: 4996) 搞定,
然后运行时报 "无法定位程序输入点CreateFile2于动态链接库KERNEL32.dll上“
从 https://msdn.microsoft.com/en-us/library/windows/desktop/hh449422(v=vs.85).aspx 可查到这玩意最少要Windows 8
才支持,我用的Windows 7.
好吧,我再来重新编译一遍。
修改上面四个工程的属性:
常规->平台工具集值由"Visual Studio 2015 (v140)"
更改为 " Visual Studio 2015 - Windows XP (v140_xp)".
哈哈, 终于,终于生成出了pdf文件。
其实libpng和libharu应当用其各自版本对应的zlib,代码会有一致性,不会出现哪个函数不支持的情况 。不过无所谓了。
我只是生成普通的pdf而已,估计够用。
附测试代码:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <setjmp.h>
#include "hpdf.h"const char *text = "This PDF should have an attachment named attach.c";jmp_buf env;#if defined(WIN32) || defined(_WIN64)#pragma warning (disable: 4996) //_s //declared deprecated ?
#endif#ifdef HPDF_DLL
void __stdcall
#else
void
#endif
error_handler(HPDF_STATUS error_no,HPDF_STATUS detail_no,void *user_data)
{printf("ERROR: error_no=%04X, detail_no=%u\n", (HPDF_UINT)error_no,(HPDF_UINT)detail_no);longjmp(env, 1);
}int
main(int argc, char **argv)
{HPDF_Doc pdf;HPDF_Font font;HPDF_Page page;char fname[256];HPDF_REAL tw;strcpy(fname, argv[0]);strcat(fname, ".pdf");pdf = HPDF_New(error_handler, NULL);if (!pdf) {printf("error: cannot create PdfDoc object\n");return 1;}if (setjmp(env)) {HPDF_Free(pdf);return 1;}/* create default-font */font = HPDF_GetFont(pdf, "Helvetica", NULL);/* add a new page object. */page = HPDF_AddPage(pdf);HPDF_Page_SetSize(page, HPDF_PAGE_SIZE_LETTER, HPDF_PAGE_PORTRAIT);HPDF_Page_BeginText(page);HPDF_Page_SetFontAndSize(page, font, 20);tw = HPDF_Page_TextWidth(page, text);HPDF_Page_MoveTextPos(page, (HPDF_Page_GetWidth(page) - tw) / 2,(HPDF_Page_GetHeight(page) - 20) / 2);HPDF_Page_ShowText(page, text);HPDF_Page_EndText(page);/* attach a file to the document *///HPDF_AttachFile(pdf, "attach.c");//HPDF_AttachFile(pdf, "jpeg_demo.c");/* save the document to a file */HPDF_SaveToFile(pdf, fname);/* clean up */HPDF_Free(pdf);return 0;
}
BLOG: http://blog.csdn.net/xcl168