近日,在下想在Adobe Reader上做点应用开发,可怎想遇到了,不能解决的难题,也
曾试着用了些方法,但是都不奏效。所以恳请看雪牛人给予指点,在下不胜感激。
事情的起因:应朋友之邀,为其做个生成pdf文件的后台程序。我选用了微软的VC++
6.0作为开发环境。按照以前的开发经验,只要能找到实现生成pdf文件相应DLL、Lib、以
及头文件,即可。经Google查之,Adobe公司只对付费购买了Reader用户才提供相应的
DLL,经与朋友确认,他没有付费版本的Reader。那就再Google,最后还是在国内某网
站,下载到了免费的AdobePDFL.dll文件。但就是它,给我带来了若干问题。
调试步骤:1、虽然是拿到了免费的DLL,但我心里还是有点不放心。我先用VC++6.0
自带的Depends工具查了一下AdobePDFL.dll,该有的接口函数都有,相关的DLL也能找
到。嗯,可以开始了。
2、像往常一样,编写代码如下:
<a> HINSTANCE hInst;
<b> hInst = LoadLibrary( "AdobePDFL.dll" );
<c> typedef ASText (*AddressFunction)(const char *);
<d> FARPROC proc = GetProcAddress(hInst, "ASAtomFromString");
<e> AddressFunction pFunc = reinterpret_cast<AddressFunction>(proc);
<f> pFunc("df");
问题如期而至,代码运行到<b>、<d>、<e>时,均能正确返回,执行<f>时,调试器
报程序访问非法空间,程序跑飞。那就开始调试吧,先看<b>执行,我在<b>执行前后,
观察Windows任务管理器对应的本程序内存使用情况,的确有增加,大小也相仿。hInst
返回值非零。结论:暂且通过。再查装载地址是否正确?当跟踪到<d>、<e>两步时,与
Depends的分析结果中ASAtomFromString函数偏址作比较,结果是分毫不差。pFunc地
址非零。结论:暂且通过。执行<f>,反汇编,函数调用的前期执行正确,进入
AdobePDL.dll空间,程序跑飞。
3、原因猜想:碰到此种事情,还是静下心来,好好分析一下,先预估一下有哪些可能
原因会导致代码失效:原因a,对DLL库装载流程,理解有误,导致根本不具备执行的可
能。原因b,对Adobe Reader接口函数理解不清,导致入口参数或返回值格式不匹配,进
而导致程序跑飞。原因c,Adobe把持着对AdobePDFL.dll的使用权控制,对于未授权的开
发一律封杀。
4、逐一排查:排查原因a,我用如下代码:
hInst = LoadLibrary( "msvcrt.dll" );
typedef int (*Example)(const char *format, ...);
FARPROC where = GetProcAddress(hInst, "printf");
Example fire = reinterpret_cast<Example>(where);
fire("a");
我找了最常用的printf函数所在的msvcrt.dll,嗯,完美通过。原因a,排除嫌疑。
排查原因b,我还是要先表扬一下Adobe,他们写的函数指南,全免费,超大容量。在他们
的Reader V9.0中居然有五千多页。我一共找了四类函数用来实验入口参数和返回值的情
况:分别是既无入口参数又无返回值;返回值为普通int型、入口参数无;返回为void型、
出口参数为int型;入口参数和返回值都是地址型。很遗憾,四类情况,不下数十个函数,
均歇在最后一步的函数执行上。我不可能将这数十个函数调用的调用都搞错吧,况且还有
入口参数和返回均无的简单情况,也不能执行。所以,我的结论是:原因b,排除嫌疑。
排查原因c,这对我就有点勉为其难。无从追踪,反汇编,逐步跟吧,功力不够,也查不出
一个所以然。所以,恳请看雪大牛,不吝赐教一二。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!