导读 c++调用dll导出函数 最好用隐式链接,C++显示链接在导出的时候会更改名字,编写比较复杂 查看dll导出函数 dll文件或导

c++调用dll导出函数

最好用隐式链接,C++显示链接在导出的时候会更改名字,编写比较复杂

查看dll导出函数 dll文件或导出函数加载失败查看dll导出函数 dll文件或导出函数加载失败


隐式链接. #pragma comment(lib,"DLL项目生成的LIB文件名"),然后在需要的地主调用函数

动态库文件(dll)

编写dll

1)声明导出

在XXX.h中:

__declspec(dllexport) 函数声明

extern __declspec(dllexport) 变量声明

在XXX.cpp中:函数定义/变量定义

2)模块定义导出

添加XXX.def文件

XXX.def中添加

LIBRARY "dll文件名"

EXPORTS

函数名 @ 导出序号

变量名 CONSTANT/DATA

使用dll

1)隐式链接

#include "XXX.h" 库函数或变量的声明.

在XXX.cpp中:

__declspec(dllimport) 函数声明

2)显示链接(如果是声明方式导出,导出时需添加extern "C",否则函数名会被编译器修饰.)

#include "XXX.h" 库函数或变量的声明.

typedef 定义函数指针/变量指针.

LoadLibrary();

GetProcAddress();

FreeLibrary();

C++类导出

1)__declspec()方式声明

导出:

XXX.h:class __declspec(dllexport) 类名{};

使用:

XXX.h:class __declspec(dllimport) 类名{};

2)全局函数返回对象方式

导出:

extren "C" __declspec(dllexport) 类* CreateInstance()

{return new 类;

}使用:

隐式链接/显示链接

使用DLL中的类的成员函数

方法一:虚函数方法.

将需要使用的成员函数声明为virtual函数

方法二:转换GetProcAddress()的返回值

1)将C++修饰的成员函数名用.def文件导出新的便于使用的函数名

EXPORTS

导出函数名 = 修饰函数名

2)使用类型转换将GetProcAddress()的返回值转换为类成员函数类型

template< typename Src, typename Dest >

Dest force_cast( Src src )

{uion

{Src s;

Dest d;

} covertor;

covertor.s = src;

return covertor.d;

}typedef 返回类型 (类::*DestFunc)(参数类型)

DsetFunc pFunc = force_cast(GetProcAddress(...));

动态链接的调用步骤:

一、隐式调用

1、建立DllCnslTest工程

2、将文件DllDemo.dll、DllDemo.lib拷贝到DllCnslTest工程所在的目录

3、在DllCnslTest.h中添加如下语句:

#define DllAPI __declspec(dllimport) #pragma comment(lib,"DllDemo.lib") //在编辑器link时,链接到DllDemo.lib文件 extern "C" { DllAPI int __stdcall Max(int a,int b); }

4、在DllCnslTest.cpp文件中添加如下语句:

#include "DllCnslTest.h"//或者 #include "DllDemo.h" void main() { int value; value = Max(2,9); printf("The Max value is %d\n",value); }

5、编译并生成应用程序DllCnslTest.exe

二、显式调用

1、建立DllWinTest工程。

2、将文件DllDemo.dll拷贝到DllWinTest工程所在的目录或Windows系统目录下。

3、用vc/bin下的Dumpbin.exe的小程序,查看DLL文件(DllDemo.dll)中的函数结构。

4、使用类型定义关键字typedef,定义指向和DLL中相同的函数原型指针。

例:

typedef int(*lpMax)(int a,int b); //此语句可以放在.h文件中

5、通过LoadLibray()将DLL加载到当前的应用程序中并返回当前DLL文件的句柄。

例:

HINSTANCE hDll; //声明一个Dll实例文件句柄 hDll = LoadLibrary("DllDemo.dll");//导入DllDemo.dll动态连接库

6、通过GetProcAddress()函数获取导入到应用程序中的函数指针。

例:

lpMax Max; Max = (lpMax)GetProcAddress(hDLL,"Max"); int value; value = Max(2,9); printf("The Max value is %d",value);

7、函数调用完毕后,使用FreeLibrary()卸载DLL文件。

FreeLibrary(hDll);

8、编译并生成应用程序DllWinTest.exe

两种方法

1:隐式链接. #pragma comment(lib,"DLL项目生成的LIB文件名"),然后在需要的地主调用函数就可以了

2:显式链接.先用LoadLibraryEx加载DLL,再用GetProcAddress找到函数地址.调用函数.

怎么提取DLL文件中的导出函数呢?

用VC++自带的 Dll导出函数查询函数 DumpBin.exe 去查询。。就能知道能用什么函数。。。

我现在,遇到的是另外一个问题,我想自己开发一个 和DumpBin有相同功能的小程序,(就是在对话框中选入Dll文件,然后在 静态控件 中陈列出它所导出的接口。。) 但是不知道用哪个 API函数 来实现。。。有没有 大侠能帮帮我?!

什么工具能够监视dll文件中的函数调用及传递参数

微软有一个工具叫做dependency walker或者Visual Studio附带的一个工具dumpbin可以查看dll的导出函数名称,函数参数和调用方式(比如__cdecl或__stdcall)在工具里无法显示,需要使用IDA或者OllyDbg等反汇编器将DLL反汇编,通过定位导出函数结尾的retn指令判断参数个数和调用方式。由被调用者平栈通常为__stdcall,由调用者平栈则是__cdecl,平栈的字节数除以平台字长(例如retn 0C中的0C在x86下是除以4,在x64下除以8)即可得到参数个数(这也是通常,具体问题可能需要具体分析),至于参数意义,那就完全需要头文件支持,或者分析反汇编代码的意义了。

在IDA里,还可以使用F5快捷键将反汇编代码转换为C代码,能稍稍方便一点。

最后一个问题,至于思路的话,你可以查看DLL的导出函数,然后使用Detours类库将原来的函数HOOK一下,做个旁路,在HOOK函数中打印调用内容,这样你在日志文件或调试输出中就能看见调用规律了。纯属个人建议。

还有一个工具叫做API Monitor,能够检测API调用。

微软有一个工具叫做dependency walker或者Visual Studio附带的一个工具dumpbin可以查看dll的导出函数名称,函数参数和调用方式(比如__cdecl或__stdcall)在工具里无法显示,需要使用IDA或者OllyDbg等反汇编器将DLL反汇编,通过定位导出函数结尾的retn指令判断参数个数和调用方式。由被调用者平栈通常为__stdcall,由调用者平栈则是__cdecl,平栈的字节数除以平台字长(例如retn 0C中的0C在x86下是除以4,在x64下除以8)即可得到参数个数(这也是通常,具体问题可能需要具体分析),至于参数意义,那就完全需要头文件支持,或者分析反汇编代码的意义了。在IDA里,还可以使用F5快捷键将反汇编代码转换为C代码,能稍稍方便一点。最后一个问题,至于思路的话,你可以查看DLL的导出函数,然后使用Detours类库将原来的函数HOOK一下,做个旁路,在HOOK函数中打印调用内容,这样你在日志文件或调试输出中就能看见调用规律了。纯属个人建议。对了,还有一个工具叫做API Monitor,能够检测API调用,但是不知道能不能检测导出函数调用,你可以尝试下,我没怎么用过。

如何查看DLL中的函数名及参数

看参数和返回值是不可能的,因为参数和返回值的类型不一定是基本类型,也有可能是类、结构等,这些复合类型都是不能预知的,因此DLL不可能导出参数和返回值类型。

如果要看某个导出函数的参数,就只能查看相关的API文档,除此别无它法。但查看导出函数名是可以的,因为我们需要一个标志符来查找某个函数的入口地址,当然,也有一些DLL导出函数不能看到函数名,那是因为该DLL的发布者采用了使用数字序号定位而不是字符串定位的缘故。

用dumpbin命令查看dll中哪些函数被导出了出错

主要工具有三个1、VC自带的

dumpbin,用法如:dumpbin

/exports

mspft80.dll2、可以depends来查看依赖项3、可以用IDA

反汇编

工具来查看,加载你需要的dll,按F5就可以查看函数反汇编成C语言的代码了注:以上方法也可以用来查看exe中的

函数原型

如何使用查看DLL神器DependencyWalker

Dependency Walker软件下载:

可使用搜索下载,也可通过浏览器地址栏输入:

2模块依赖关系树视图如下:

模块依赖关系树视图显示所有模块的依赖关系的层次结构视图。以下是伴随在依赖关系树的每个模块的主图像列表。这个列表包含了所有可能的图像。实际图像可以是以下一个或多个图像的组合(如果下图看不清楚,可访问oxox.work/web/experience/dependencywalker/查看):

导入函数列表视图

导入函数列表视图显示的是在模块依赖关系树视图中当前选定的模块对应的导入函数列表。导入函数是实际上调用父模块给定的模块中的功能。

导入函数列表视图是由以下五列组成:

PI:见下面的列表说明。它表示“Parent Imports”

Ordinal:如果函数是通过序号导入,则这个值是导入函数的序号值。如果该功能是通过名字导入,这个值可以是“N/ A”。

Hint:为导入函数的提示值。它被用来作为导出函数的选择的模块中的数组的一个索引。

Function:输入函数的名称,如果该功能是通过名字进口。它可以是“N/ A”,如果函数是由序号导入。 C++函数可以在它们的天然的装饰形式或以人类可读的形式来查看。

Entry Point:入口点的内存地址,对于隐式和向前的依赖关系,该字段通常读取“Not Bound”的,这意味着所述入口点地址直到加载时间才会被知道。

以下是导入函数列表视图中的每个功能的主要图片:

导出函数列表视图

导出函数列表视图显示的是在模块依赖关系树视图中当前选定的模块对应的导出函数列表。导出函数模块提供给其他模块调用。它们可以被认为是模块的接口。

导出函数列表的五列与导入函数列表视图类似。

以下是导出函数列表视图中的每个功能的主要图片:

模块列表视图

模块列表视图显示所有依赖于你打开根模块列表的特定模块是。这个列表定义了一组需要加载和作为一个正在运行的进程执行的模块文件。

以下是模块列表视图中Module的每个功能的主要图片:

该模块列表视图中包含的每个模块的信息总共有以下多列。这些列包括:

日志视图

如果DependencyWalker在解析某个DLL文件时出错,错误信息会显示在该模块中。就如下图打开的一个带有错误的DLL文件。