分享
 
 
 

隐式链接无.LIB动态链接库

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

由于我们经常要调用一些第三方厂商或其他编译器编写的动态链接库,但是一般都不提供源文件或.lib文件,而作为VC隐式链接到DLL(implicitly link to the DLL)调用,这些却是必需的。本文将主要讨论在没有源文件及.lib输入库文件或欲调用Windows未公开函数的情况下重建.Lib文件的方法。在建立之前,我们首先要了解一下DLL输出函数的几种方式。

一、从DLL中输出函数的方式(calling conventions)

_cdecl是C和C++程序的缺省调用方式。每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大。函数采用从右到左的压栈方式。VC将函数编译后会在函数名前面加上下划线前缀。

_stdcall是Pascal程序的缺省调用方式,通常用于Win32 Api中,函数采用从右到左的压栈方式,自己在退出时清空堆栈。VC将函数编译后会在函数名前面加上下划线前缀,在函数名后加上"@"和参数的字节数。

_fastcall方式的函数采用寄存器传递参数,VC将函数编译后会在函数名前面加上"@"前缀,在函数名后加上"@"和参数的字节数。

用VC建立一个空的动态链接库,并加入以下三个文件:

//noname.h 动态链接库头文件

extern "C" void _stdcall stdcallproc(void);

extern "C" void _cdecl cdeclproc(void);

extern "C" void _fastcall fastcallproc(void);

//noname.cpp 动态链接库实现文件

#include

extern "C" void _stdcall stdcallproc(void)

{ MessageBox(0,"stdcall function","dll call",0);

}

extern "C" void _cdecl cdeclproc(void)

{ MessageBox(0,"cdecl function ","dll call",0);

}

extern "C" void _fastcall fastcallproc(void)

{ MessageBox(0,"fastcall function ","dll call",0);

}

//noname.def 动态链接库输出函数定义

LIBRARY "noname"

EXPORTS

stdcallproc @1 noname

cdeclproc @2

fastcallproc @3

编译后生成noname.lib,输出函数_cdeclproc,_stdcallproc@0,@fastcallproc@0;生成的noname.dll在Exescope等PE格式的工具中只能看到cdeclproc和fastcallproc函数,因为stdcallproc被指定noname属性,没有名字输出,类似于Windows未公开函数。

二、可执行程序调用DLL的方式

可执行程序可以采用隐式链接(implicit linking)或显式链接(explicit linking)两种方式调用一个DLL。

使用显式链接时,使用DLL的程序在使用之前必须加载(LoadLibrary)加载DLL从而得到一个DLL模块的句柄,然后调用GetProcAddress函数得到输出函数的指针,在退出之前必须卸载DLL(FreeLibrary),因为不是本文重点,具体例程请参考有关文档。显然,在调用大量的函数时这种方法会很不方便。

使用隐式链接时,可执行程序链接到一个包含DLL输出函数信息的输入库文件(.LIB文件)。操作系统在加载使用可执行程序时加载DLL。可执行程序直接通过函数名调用DLL的输出函数,调用方法和程序内部其他的函数是一样的。

三、重建.Lib输入库文件

根据微软的建议,要想隐式地链接到一个DLL,可执行程序必须从DLL的提供者那儿得到一个包含输出函数的头文件(.h文件)、一个用于链接的输入库(.lib文件)。愿望是很好的,但是一般情况下,我们都无法得到第三方动态链接库的输入库文件,或者我们需要调用Windows未公开函数。如果你是使用Delphi或Visual Basic开发程序,那么,你只要简单的申明一下函数和输出库就可以了。但是,使用VC的朋友们只好重建.Lib文件了。

1.删掉第一步中生成的noname.lib(假设我们没有这个文件)。

2.用微软的DumpBin.exe:dumpbin /exports noname.dll>noname.def,留下noname.def文件的输出段:

ordinal hint RVA name

2 0 00001005 cdeclproc

3 1 0000100F fastcallproc

1 0000100A [NONAME]

修改为:

LIBRARY "noname"

EXPORTS

cdeclproc @2

fastcallproc @3

nonameproc @1 //请注意与第一步中noname.def的区别:nonameproc可以自己指定为任何名字

再执行lib.exe /def:noname.def即可生成noname.lib文件(但如果这个动态链接库不仅仅包含_cdecl类型函数,那么这个noname.lib还不是最终可用的.lib文件,具体请看下文)。

3.建立一个名为DllCaller的Win32控制台程序,将刚才生成的noname.dll和noname.lib拷入DllCallerdebug目录。

//DllCaller.cpp

//声明函数原型

extern "C" void _stdcall nonameproc(void);

extern "C" void _cdecl cdeclproc(void);

extern "C" void _fastcall fastcallproc(void);

//链接输入库文件

#pragma comment(lib,"debug\noname.lib")

int main(int argc, char* argv[])

{

nonameproc();

cdeclproc();

fastcallproc();

return 0;

}

编译器产生如下错误:

DllCaller.obj : error LNK2001: unresolved external symbol @fastcallproc@0

DllCaller.obj : error LNK2001: unresolved external symbol _nonameproc@0

根据错误提示信息将noname.def更改如下:

@fastcallproc@0 @3

nonameproc@0 @1

重新生成noname.lib,即可重新编译DllCaller.exe。

四、调用Windows未公开函数

根据以上分析,下面给出一个简单的调用Window98系统Shell32.DLL中序号为60的未公开函数,执行后将出现重新启动的对话框。

//shell32.def,据此生成Shell32.LIB

LIBRARY "shell32"

EXPORTS

SHShutDownDialog@4 @60

// DllCaller.cpp:调用未公开函数的控制台程序

//函数声明

extern "C" long _stdcall SHShutDownDialog(long lShutdown);

//链接输入库文件

#pragma comment(lib,"debug\shell32.lib")

int main(int argc,char* argv[])

{

SHShutDownDialog(0);

return 0;

}

本文所有程序在VC6.0,Windows98SE环境下调试通过,也希望这些程序对于用VC的朋友有所帮助。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有