dumpbin查看dll中函数名字的问题

利用微软的dumpbin.exe我们可以方便的查看dll中的函数名字,为了能利用命令行,我们要首先把C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin设置为path环境变量,这个时候运行命令:

dumpbin -exports  xx.dll

此时会出现一个问题,说是缺少mspdb100.dll ,这个时候我们从C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE中复制mspdb100.dll,运行上面的命令,发现OK,可以看到dll中的函数名字,但是问题在此时就又出现了,我们重新编译程序,会出现这样的错误:

fatal error C1902: 程序数据库管理器不匹配;请检查安装

这个时候我们把刚才复制过来的mspdb100.dll删除,然后再重新编译程序,发现错误就没了,难道以后要用dumpbin就必须这么麻烦吗,添加,然后删除?

答案是有的,我们需要从C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE把mspdbsrv.exe也复制到bin里面,这样再重新编译的时候就不会出错了?


不过还是不理解微软要这么做,放了一个exe在bin里面,却不把相关的依赖文件放进去?


实例程序:

addF.h

#ifndef _ADDFULL_H
#define _ADDFULL_H

extern "C" _declspec(dllexport) int add(int x,int y);
_declspec(dllexport) int sub(int x,int y);
_declspec(dllexport) int _stdcall mul(int x,int y);
#endif

addF.cpp

#include "stdafx.h"
#include "addF.h"

int add(int x,int y)
{
	return x + y;
}
int sub(int x,int y)
{
	return x - y;
}

int _stdcall mul(int x,int y)
{
	return x * y;
}

生成的dll我们查看其内容显示如下所示:

dumpbin查看dll中函数名字的问题_第1张图片

从图上我们可以明显的看到dll中的函数名字,其中用 extern “C” 声明的函数,其名字和函数原来的名字一样,add;

其余两个函数的名称在导出时候就多了前缀和后缀,因为他们是C++的编译方式,其中函数的前缀后缀还是有所不同 的,先说

_declspec(dllexport)  int sub(int,int),它的函数调用方式是缺省的_cdel,所以函数名字被解析为 ?sub@@YAHHH@Z,其中YA代表_cdel调用,YA后面第一个字母H代表函数的

返回类型是int,后面两个H代表函数的两个int形参,@z代表函数的结束。

_declspec(dllexport)  int  _stdcall mul(int,int)它的函数调用方式是_stdcall,函数名字被解析为?mul@@YGHHH@Z,其中YG代表_stdcall,剩下的意思跟_cdel中的一样。

所以说在这点还是要注意的。


另谈函数的调用方式对函数名字的影响:

C++,C中的两种调用方式,默认的是_cdecl,另外一个是stdcall,如果我们用默认的_cdecl来调用的话就,如下所示:

extern "C" _declspec(dllexport) int add(int x,int y);
extern "C" _declspec(dllexport) int sub(int x,int y);
_declspec(dllexport) int  _stdcall mul(int x,int y);
函数导出的名字就会是:


dumpbin查看dll中函数名字的问题_第2张图片

如果是:

extern "C" _declspec(dllexport) int add(int x,int y);
extern "C" _declspec(dllexport) int sub(int x,int y);
extern "C" _declspec(dllexport) int _stdcall mul(int x,int y);
那么结果就会是:

dumpbin查看dll中函数名字的问题_第3张图片

这说明在stdcall调用方式下,如果加上extern “C”,那么函数名字就会变成 _funcName@Num,其中的num代表参数占用的字节数,

但是如果不加extern “C”的话,函数名字就完全是C++中的那种添加前后缀的形式

在cdecl调用方式下,如果加上extern “C”,函数导出的名字就和函数原本的名字一样,(这一点是两种调用方式不同点所在)

去掉extern “C”,那么函数名字就是C++中的添加前后缀(这点和stdcall的结果一样)。

你可能感兴趣的:(dumpbin查看dll中函数名字的问题)