DLL断点调试
一般来说调试DLL是把DLL工程和exe工程放到一个解决方案里。如果不放到一个解决方案里,那两者的输出目录要一致,属性-连接器-常规-输出目录。保证dll,dll的pdb,exe,exe的pdb在一个文件夹内。
dll 导出函数名的那些事关键字: VC++ DLL 导出函数 经常使用VC6的Dependency查看DLL导出函数的名字,会发现有DLL导出函数的名字有时大不相同,导致不同的原因大多是和编译DLL时候指定DLL导出函数的界定符有关系。VC++支持两种语言:即C/C++,这也是造成DLL导出函数差异的根源我们用VS2008新建个DLL工程,工程名为"TestDLL"把默认的源文件后缀 .CPP改为.C(C文件)输入测试代码如下:01 int _stdcall MyFunction(int iVariant)02 {03 return 0;04 }为了导出上面这个函数,我们有以下几个方法:1. 使用传统的模块定义文件 (.def)新建一个 后缀为.def的文本文件(这里建一个TestDll.Def),文件内容为:LIBRARY TestDllEXPORTSMyFunction在 Link 时指定输入依赖文件:/DEF:"TestDll.Def"2. Visual C++ 提供的方便方法在01行的int 前加入 __declspec(dllexport) 关键字通过以上两种方法,我们就可以导出MyFunction函数。我们用Dependency查看导出的函数:第一种方法导出的函数为:MyFunction第二种方法导出的函数为:_MyFunction@4__stdcall会使导出函数名字前面加一个下划线,后面加一个@再加上参数的字节数,比如_MyFunction@4的参数(int iVariant)就是4个字节__fastcall与 __stdcall类似,不过前面没有下划线,而是一个@,比如@MyFunction@4__cdecl则是始函数名。小结:如果要导出C文件中的函数,并且不让编译器改动函数名,用def文件导出函数。下面我们来看一下C++文件我们用VS2008新建个DLL工程,工程名为"TestDLL"默认的源文件后缀为 .CPP (即C++文件)。输入测试代码如下:01 int _stdcall MyFunction(int iVariant)02 {03 return 0;04 }为了导出上面这个函数,我们有以下几个方法:3. 使用传统的模块定义文件 (.def)新建一个 后缀为.def的文本文件(这里建一个TestDll.Def),文件内容为:LIBRARY TestDllEXPORTSMyFunction在 Link 时指定输入依赖文件:/DEF:"TestDll.Def"4. Visual C++ 提供的方便方法在01行的int 前加入 __declspec(dllexport) 关键字通过以上两种方法,我们就可以导出MyFunction函数。我们用Dependency查看导出的函数:第一种方法导出的函数为:MyFunction第二种方法导出的函数为:?MyFunction@@YGHH@Z可以看到 第二种方法得到的 导出函数名 并不是我们想要的,如果在exe中用显示方法(LoadLibrary、GetProcAddress)调用 MyFunction 肯定会失败。但是用引入库(*.LIB)的方式调用,则编译器自动处理转换函数名,所以总是没有问题。解决这个问题的方法是:用VC 提供的预处理指示符 "#pragma" 来指定链接选项。如下:#pragma comment(linker, "/EXPORT:MyFunction=?MyFunction@@YGHH@Z")这时,就会发现导出的函数名字表中已经有了我们想要的MyFunction。但我们发现原来的那个 ?MyFunction@@YGHH@Z 函数还在,这时就可以把 __declspec() 修饰去掉,只需要 pragma 指令即可。而且还可以使如下形式:#pragma comment(linker, "/EXPORT:MyFunction=_MyFunction@4,PRIVATE")PRIVATE 的作用与其在 def 文件中的作用一样。更多的#pragram请查看MSDN。小结:如果要导出C++文件中的函数,并且不让编译器改动函数名,用def文件导出函数。同时可以用#pragma指令(C 中也可以用)。总结:C++编译器在生成DLL时,会对导出的函数进行名字改编,并且不同的编译器使用的改编规则不一样,因此改编后的名字也是不同的(一般涉及到C++ 中的重载等)。如果利用不同编译器分别生成DLL和访问DLL的exe程序,后者在访问该DLL的导出函数时就会出现问题。如上例中函数MyFunction在C++编译器改编后的名字是?MyFunction@@YGHH@Z。我们希望编译后的名字不发生改变,这里有几种方法。第一种方法是通过一个称为模块定义文件DEF来解决。LIBRARY TestDllEXPORTSMyFunctionLIBRARY 用来指定动态链接库内部名称。该名称与生成的动态链接库名一定要匹配,这句代码不是必须的。EXPORTS说明了DLL将要导出的函数,以及为这些导出函数指定的符号名。第二种是定义导出函数时加上限定符:extern "C"如:#define DLLEXPORT_API extern "C" _declspec(dllexport)但extern "C"只解决了C和C++语方之间调用的问题(extern "C" 是告诉编译器,让它按C的方式编译),它只能用于导出全局函数这种情况 而不能导出一个类的成员函数。同时如果导出函数的调用约定发生改变,即使使用extern "C",编译后的函数名还是会发生改变。例如上面我们加入_stdcall关键字说明调用约定(标准调用约定,也就是WINAPI调用约定)。#define DLLEXPORT_API extern "C" _declspec(dllexport)01 DLLEXPORT_API int _stdcall MyFunction(int iVariant)02 {03 return 0;04 }编译后函数名MyFunction改编成了_MyFunction@4通过第一种方法模块定义文件的方式DLL编译后导出函数名不会发生改变。DLL(动态库)导出函数名乱码含义C++编译时函数名修饰约定规则: __stdcall调用约定: 1、以"?"标识函数名的开始,后跟函数名; 2、函数名后面以"@@YG"标识参数表的开始,后跟参数表; 3、参数表以代号表示: X--void D--char E--unsigned char F--short H--int I--unsigned int J--long K--unsigned long M--float N--double _N--bool .... PA--表示指针,后面的代号表明指针类型,如果相同类型的指针连续出现,以"0"代替,一个"0"代表一次重复; 4、参数表的第一项为该函数的返回值类型,其后依次为参数的数据类型,指针标识在其所指数据类型前; 5、参数表后以"@Z"标识整个名字的结束,如果该函数无参数,则以"Z"标识结束。 其格式为"?functionname@@YG*****@Z"或"?functionname@@YG*XZ",例如 int Test1(char *var1, unsigned long)-----"?Test1@@YGHPADK@Z" void Test2()-----"?Test2@@YGXXZ" __cdecl调用约定: 规则同上面的_stdcall调用约定,只是参数表的开始标识由上面的"@@YG"变为"@@YA"。 __fastcall调用约定: 规则同上面的_stdcall调用约定,只是参数表的开始标识由上面的"@@YG"变为"@@YI"。 如果要用DEF文件输出一个"C++"类,则把要输出的数据和成员的修饰名都写入.def模块定义文件 所以... 通过def文件来导出C++类是很麻烦的,并且这个修饰名是不可避免的http://blog.csdn.net/iw1210/article/details/29615569
http://www.360doc.com/content/12/0914/09/6973384_236025844.shtml
http://blog.163.com/fenglanghai@126/blog/static/3356877920116555810161/
http://blog.csdn.net/srzhz/article/details/7033985
http://blog.163.com/bbluesnow@126/blog/static/277845452012123114924563/
http://blog.sina.com.cn/s/blog_6a2236590100xbgl.html
http://blog.csdn.net/shandiantianying/article/details/11039733
http://blog.csdn.net/xiaolongwang2010/article/details/8496177
DLL断点调试的更多相关文章
- delphi 2010 动态链接库DLL断点调试
DELPHI 2010 动态链接库DLL断点调试 马根峰 (广东联合电子服务股份有限公司,广州 510300) 摘要:本文详细介绍了Delphi 2010中的动态链接库DLL断点调试技术 关键词:DE ...
- c语音 dll断点调试方法
转自:https://blog.csdn.net/qingzai_/article/details/45348613 dll调试方法: 1.把最新生成的dll和pdb放到 启动这个dll 的进程目录下 ...
- Delphi dll 断点调试
1.dll 要有一个依托的exe(怎么做 相信用dll了一定知道) 2.选项中的compling中的debugging中的选项,linking中的所有选项 3.最后一个也就是最重要的 run中的par ...
- 采用Reflector的VS.net插件断点调试无源码DLL 分类:
.Net的编程利器Reflector可以反编译基于.net开发的应用程序和DLL,其功能强大不用多说.今天想试验一把利用VS.net的插件断点调试外部无源码的DLL(只要是程序集都可以,所以exe也行 ...
- PhpStorm集成xdebug进行断点调试
本文介绍如何使用PhpStorm集成xdebug在本地开发环境进行断点调试的技巧. 我配置的环境是:Windows10 + PhpStorm10.0.1 + PHP5.6. 1. 下载xdebug的扩 ...
- netbeans-xdebug 断点调试php
来自NetBeans官网的帮助文档: https://netbeans.org/kb/docs/php/debugging_zh_CN.html 但具体问题,我们还是要说下 准备工作 本地部署的ser ...
- 在VS2015中用C++创建DLL并用C#调用且同时实现对DLL的调试
from:http://m.blog.csdn.net/article/details?id=51075023 在VS2015中先创建C#项目,然后再创建要编写的动态库DLL项目,这样做的好处是整个解 ...
- 最新为Phpstorm配置xdebug 进行断点调试
额 ,曾经写过一个,现在发现不咋好使了 ,你说咋整,下载xdebug的时候 还得注意系统是32位还是64位,而且一堆下载文件不知道是哪个. 额,所以我现在发现有个更好的方法,啥也不下了 直接配把 ...
- 【转】说说如何使用unity Vs来进行断点调试
大家可以从这下载最新版的unity vs. UnityVs1.81下载 1. 安装unity vs.首先我们打开我们下载的unity vs.然后就会看见里面有3个文件,我们双击UnityVS 2 ...
随机推荐
- 【springboot】【socket】spring boot整合socket,实现服务器端两种消息推送
参考地址:https://www.cnblogs.com/hhhshct/p/8849449.html
- 1.2 Stream API
引例: List<String> strList = Arrays.asList("zhaojigang","nana","tianya& ...
- 【Storm】一张图搞定Storm的运行架构
- Java高编译低运行错误(ConcurrentHashMap.keySet)
Java高编译低运行错误(ConcurrentHashMap.keySet) 调了一天: https://www.jianshu.com/p/f4996b1ccf2f
- MySQL 大致测试更新时间
1:需求:把一个2千万条数据的一个表,随机更新其中的二十行需要大致多久? DROP TABLE IF EXISTS test20; CREATE TABLE test20( id INT AUTO_I ...
- (原)Show, Attend and Translate: Unsupervised Image Translation with Self-Regularization and Attention
转载请注明出处: https://www.cnblogs.com/darkknightzh/p/9333844.html 论文网址:https://arxiv.org/abs/1806.06195 在 ...
- 浅析Sql Server参数化查询
说来惭愧,工作差不多4年了,直到前些日子被DBA找上门让我优化一个CPU占用很高的复杂SQL语句时,我才突然意识到了参数化查询的重要性. 相信有很多开发者和我一样对于参数化查询认识比较模糊,没有引起足 ...
- 【Windows】查看Windows上运行程序的异常日志
任何在windows系统上运行的程序,只要发生异常导致程序异常终止,windows都会在日志中详细记录这个异常.可以在计算机管理中查看,如图:也可以在操作中心查看,如图:
- 基于Tcp协议的简单Socket通信实例(JAVA)
好久没写博客了,前段时间忙于做项目,耽误了些时间,今天开始继续写起~ 今天来讲下关于Socket通信的简单应用,关于什么是Socket以及一些网络编程的基础,这里就不提了,只记录最简单易懂实用的东西. ...
- Java日志框架(Commons-logging,SLF4j,Log4j,Logback)
简介 在系统开发中,日志是很重要的一个环节,日志写得好对于我们开发调试,线上问题追踪等都有很大的帮助.但记日志并不是简单的输出信息,需要考虑很多问题,比如日志输出的速度,日志输出对于系统内存,CPU的 ...