最近入手了一台Kindle,想在上面看代码.发现直接放上去看不了。
好吧,就准备写个批量将代码文件自动转成带目录标签的PDF文件的程序。
找到了libharu这个开源库,准备开用,没想到要用起来真不容易。
下面是折腾记录。
开发环境: VS Express 2015 版本
相关工程下载
从github下载libharu
下载zlib
下载libpng
编译 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
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