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 ...
随机推荐
- windows Server 2008 R2 开关机取消登录时要按Ctrl+Alt+Delete组合键登录的方法
1.点桌面任务栏的“开始-->运行”在弹出的窗口中输入gpedit.msc . 2.找到如下图所示的位置 右键属性进行设置如下
- pyqt QFileDialog
from PyQt5 import QtWidgetsfrom PyQt5.QtWidgets import QFileDialog class MyWindow(QtWidgets.QWidget) ...
- C++ 中的位操作
定义二进制变量: 一般是以八进制或者十六进制来定义,八进制数以0开头,十六进制数以0x开头 例如int a = 0x80, 这里的80只能表示8个二进制位,它表示的是int的低8位,前面的24个二进 ...
- 使用VirtualBox在Ubuntu下虚拟Windows XP共享文件夹设置方法
1.首先保证虚拟的Windows XP有虚拟光驱(正常安装的都是有的,因为在ubuntu下一般都是用硬盘虚拟安装的),然后在已经运行起来的Windows XP菜单栏上选择“设备-安装增强功能“,如果不 ...
- MySQL 四种事务隔离级的说明[转]
很早之前写的文章,重新回顾和学习下: 按照SQL:1992 事务隔离级别,InnoDB默认是可重复读的(REPEATABLE READ).MySQL/InnoDB 提供SQL标准所描述的所有四个事务隔 ...
- 【FTP】FTP服务器的搭建
记录一下FTP服务器的搭建首先打开 程序和功能>打开或关闭Windows功能 进入到Windows功能界面:勾选FTP服务器.然后再在IIS界面,新建一个网站.右键网站,选择“添加到FTP发布” ...
- spring-mybatis-data-common程序级分表操作实例
spring-mybatis-data-common-2.0新增分表机制,在1.0基础上做了部分调整. 基于机架展示分库应用数据库分表实力创建 create table tb_example_1( i ...
- Mydumper介绍
Mydumper是一个针对MySQL和Drizzle的高性能多线程备份和恢复工具.开发人员主要来自MySQL,Facebook,SkySQL公司.目前已经在一些线上使用了Mydumper. 一.Myd ...
- 在代码中设置RelativeLayout布局中标签的android:layout_toLeftOf、android:layout_toRightOf等属性
需要动态改变RelativeLayout里面控件的相对位置,经一个技术群的群友提示,找到了如下的方法,做下记录: RelativeLayout.Layoutparams params = (Rel ...
- css自适应浏览器大小
css自适应浏览器大小 1.屏幕 > 900px :显示3列 2.450px < 屏幕 < 900px :显示2列 3.屏幕 < 450px :显示1列 <!DOCTYP ...