科技报道|exe调用DLL的方式( 二 )
而使用_declspec(dllimport)却不是必须的 , 但是建议这么做 。 因为如果不用_declspec(dllimport)来说明该函数是从dll导入的 , 那么编译器就不知道这个函数到底在哪里 , 生成的exe里会有一个callXX的指令 , 这个XX是一个常数地址 , XX地址处是一个jmpdwordptr[XXXX]的指令 , 跳转到该函数的函数体处 , 显然这样就无缘无故多了一次中间的跳转 。 如果使用了_declspec(dllimport)来说明 , 那么就直接产生calldwordptr[XXX] , 这样就不会有多余的跳转了 。
2|3__stdcall带来的影响这是一种函数的调用方式 。 默认情况下VC使用的是__cdecl的函数调用方式 , 如果产生的dll只会给C/C++程序使用 , 那么就没必要定义为__stdcall调用方式 , 如果要给Win32汇编使用(或者其他的__stdcall调用方式的程序) , 那么就可以使用__stdcall 。 这个可能不是很重要 , 因为可以自己在调用函数的时候设置函数调用的规则 。 像VC就可以设置函数的调用方式 , 所以可以方便的使用win32汇编产生的dll 。 不过__stdcall这调用约定会Name-Mangling , 所以我觉得用VC默认的调用约定简便些 。 但是 , 如果既要__stdcall调用约定 , 又要函数名不给修饰 , 那可以使用*.def文件 , 或者在代码里#pragma的方式给函数提供别名(这种方式需要知道修饰后的函数名是什么) 。
举例:
·extern“C”__declspec(dllexport)bool__stdcallcswuyg();·extern“C”__declspec(dllimport)bool__stdcallcswuyg();·#pragmacomment(linker,"/export:cswuyg=_cswuyg@0")3|0编写测试dll代码项目结构:
LIBRARYDLLTESTEXPORTSprintM项目属性中将配置类型改为dll:
执行结果:
#include#includeusingnamespacestd;intmain(){HINSTANCEh=LoadLibrary(L"C:projectdlltestDebugdlltest.dll");if(h==NULL){cout<<"dll加载失败!"<<endl;}else{void*func=GetProcAddress(h,"printN");if(func!=NULL){((void(*)(int))func)(2);}else{cout<<"未找到相关函数!"<<endl;}}return0;}需要注意将项目的字符集改为Unicode:
推荐阅读
- 无趣科技谈|X2凭实力拿下冠军,京东手机周销量榜单出炉,Find
- 毛毛科技说|三星S20+出现“小米价”,总算等到了,三星扛不住了
- 简简科技|余承东称鸿蒙体验已达安卓7成多,鸿蒙手机新进展
- ITheat热点科技|2020 | 坚持创新 舒尔带来MXA710音频解决方案,SSOT
- 空心|招聘丨山西千沐云物联科技有限公司
- LeoGo科技|科沃斯除菌地宝N8和米家扫拖机器人横评——两款解放双手的精品
- 小绿叶子科技|半年跌1000元,适合捡漏,iPhoneSE2扛不住了
- 电科技|“吃鸡”手游老是瞄不准?不妨选这款游戏外设配件
- 科技日日说|realme真我X7全方位评测:不一样的颜值,不一样的体验!,原创
- 硅谷聊科技|就不愿再用华为、小米了?,答案确认了!为啥很多人用了iPhone后