`
javasogo
  • 浏览: 1837512 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

DLL导出函数和类

阅读更多

Dll导出函数和类的方法有三种:

1. 源代码中的 __declspec(dllexport)

2. .def 文件中的 EXPORTS 语句

3. LINK 命令中的 /EXPORT 规范

所有这三种方法可以用在同一个程序中。LINK 在生成包含导出的程序时还创建导入库,除非生成中使用了 .exp 文件。

三者的不同之处:__declspec(dllexport)导出变量方法类很简单,也可以指定C类型约定导出(加extern “C”),但是如果你的DLL是供VB PBDelphi用户使用的,那么会产生一个小麻烦。因为VC++对于__declspec(dllexport)声明的函数会进行名称转换,如下面的函数:

__declspec(dllexport) int __stdcall IsWinNT()

会转换为IsWinNT@0,这样你在VB中必须这样声明:

Declare Function IsWinNT Lib "my.dll" Alias "IsWinNT@0" () As Long

@的后面的数由于参数类型不同而可能不同。这显然不太方便。所以如果要想避免这种转换,就要使用.def文件方式。

.def文件是模块定义文件,使用.def文件可以DLL 导出函数,也可以通过在函数名的后面加上 @ 符和一个数字,给函数分配序号值。当指定序号值时,序号值的范围必须是从 1 N,其中 N DLL 导出函数的个数。

LINK 命令中的 /EXPORT 规范是通过预处理指示符 “#pragma” 来指定链接选项来快捷导出DLL函数,比如:

#pragma comment(linker, "/EXPORT:MyExportFunction=_MyExportFunction@4,PRIVATE")

一、使用 __declspec(dllexport) DLL 导出

Microsoft Visual C++ 16 位编译器版本中引入了 __export,使编译器得以自动生成导出名并将它们放到一个 .lib 文件中。然后,此 .lib 文件就可以像静态 .lib 那样用于与 DLL 链接。

在更新的32位编译器版本中,可以使用 __declspec(dllexport) 关键字从 DLL 导出数据、函数、类或类成员函数。__declspec(dllexport) 会将导出指令添加到对象文件中,因此您不需要使用 .def 文件。

当试图导出 C++ 修饰函数名时,这种便利最明显。由于对名称修饰没有标准规范,因此导出函数的名称在不同的编译器版本中可能有所变化。如果使用 __declspec(dllexport),仅当解决任何命名约定更改时才必须重新编译 DLL 和依赖 .exe 文件。

许多导出指令(如序号、NONAME PRIVATE)只能在 .def 文件中创建,并且必须使用 .def 文件来指定这些属性。不过,在 .def 文件的基础上另外使用 __declspec(dllexport) 不会导致生成错误。

若要导出函数,__declspec(dllexport) 关键字必须出现在调用约定关键字的左边(如果指定了关键字)。例如:

__declspec(dllexport) void __cdecl Function1(void);若要导出类中的所有公共数据成员和成员函数,关键字必须出现在类名的左边,如下所示:

class __declspec(dllexport) CExampleExport : public CObject{ ... class definition ... };生成 DLL 时,通常创建一个包含正在导出的函数原型和/或类的头文件,并将 __declspec(dllexport) 添加到头文件中的声明中。若要提高代码的可读性,请为 __declspec(dllexport) 定义一个宏并对正在导出的每个符号使用该宏:

#define DllExport __declspec( dllexport )

二、使用 DEF 文件从 DLL 导出

模块定义 (.def) 文件是包含一个或多个描述 DLL 各种属性的 Module 语句的文本文件。如果不使用 __declspec(dllexport) 关键字导出 DLL 的函数,则 DLL 需要 .def 文件。

.def 文件必须至少包含下列模块定义语句:

· 文件中的第一个语句必须是 LIBRARY 语句。此语句将 .def 文件标识为属于 DLLLIBRARY 语句的后面是 DLL 的名称。链接器将此名称放到 DLL 的导入库中。

· EXPORTS 语句列出名称,可能的话还会列出 DLL 导出函数的序号值。通过在函数名的后面加上 @ 符和一个数字,给函数分配序号值。当指定序号值时,序号值的范围必须是从 1 N,其中 N DLL 导出函数的个数。

例如,包含实现二进制搜索树的代码的 DLL 看上去可能像下面这样:

LIBRARY BTREE

EXPORTS

Insert @1

Delete @2

Member @3

Min @4

如果使用 MFC DLL 向导创建 MFC DLL,则向导将为您创建主干 .def 文件并将其自动添加到项目中。添加要导出到此文件的函数名。对于非 MFC DLL,必须亲自创建 .def 文件并将其添加到项目中。

如果导出 C++ 文件中的函数,必须将修饰名放到 .def 文件中,或者通过使用外部“C”定义具有标准 C 链接的导出函数。如果需要将修饰名放到 .def 文件中,则可以通过使用 DUMPBIN 工具或 /MAP 链接器选项来获取修饰名。请注意,编译器产生的修饰名是编译器特定的。如果将 Visual C++ 编译器产生的修饰名放到 .def 文件中,则链接到 DLL 的应用程序必须也是用相同版本的 Visual C++ 生成的,这样调用应用程序中的修饰名才能与 DLL .def 文件中的导出名相匹配。

如果生成扩展 DLL 并使用 .def 文件导出,则将下列代码放在包含导出类的头文件的开头和结尾:

#undef AFX_DATA

#define AFX_DATA AFX_EXT_DATA

// <body of your header file>

#undef AFX_DATA

#define AFX_DATA

这些代码行确保内部使用的 MFC 变量或添加到类的变量是从扩展 DLL 导出(或导入)的。例如,当使用 DECLARE_DYNAMIC 派生类时,该宏扩展以将 CRuntimeClass 成员变量添加到类。省去这四行代码可能会导致不能正确编译或链接 DLL,或在客户端应用程序链接到 DLL 时导致错误。

当生成 DLL 时,链接器使用 .def 文件创建导出 (.exp) 文件和导入库 (.lib) 文件。然后,链接器使用导出文件生成 DLL 文件。隐式链接到 DLL 的可执行文件在生成时链接到导入库。请注意,MFC 本身使用 .def 文件从 MFCx0.dll 导出函数和类。

注意细节问题:

1使用 MFC DLL 向导创建 MFC DLL,则向导将为您创建主干 .def 文件并将其自动添加到项目中。添加要导出到此文件的函数名。对于非 MFC DLL,必须亲自创建 .def 文件并将其添加到项目中。

2、通过.def文件导出函数和类时,最好通过添加一个新的项目名.def问题,将需要导出的函数和类写入其中。

3DLL.def文件不起作用

解决方法:

1) 打开工程属性页。比如

2) 选择连接器目录

3) 单击输入属性

4) 修改模版定义文件属性。加入项目名.def文件。

4 DLL 源代码从 Win16 移植到 Win32 时,请用 __declspec(dllexport) 替换 __export 的每个实例。

5DLL隐式链接与显示链接

DLL隐式链接:通过链接Lib库,然后加入需要导入的变量、函数、类并且在之前加_declspec(dllimport) ,自然直接使用DLL中的函数和类。

DLL显示链接:通过LoadLibrary加载dll,然后通过GetProcAddress得到函数,就可以使用DLL中的函数。(不需要lib文件)

举例:
Dll
程序:
__declspec(dllexport) int g_xua = 10;
__declspec(dllexport) void __cdecl myPrint()
{
printf("I am in dll\n");
}
隐式链接调用:
链接Lib
_declspec(dllimport) int g_xua;
_declspec(dllimport) void myPrint();
显示链接调用:
typedef int (__cdecl *MYPROC)();
hinstLib = LoadLibrary(TEXT("UsedDll"));
if(hinstLib == NULL)
{

AfxMessageBox("GetModuleHandle fail");

}
PVOID procAddress1 =
GetProcAddress(hinstLib,(LPCSTR)MAKEINTRESOURCE(1));
if(procAddress1 == NULL)

{

AfxMessageBox("GetProcAddress fail");

}
int* show_g_xua = (int*)procAddress1;
printf("g_xua=%d\n",*show_g_xua);

MYPROC procAddress2 = (MYPROC)GetProcAddress(hinstLib,(LPCSTR)MAKEINTRESOURCE(2));
if(procAddress2 == NULL)

{

AfxMessageBox("GetProcAddress fail");

}
procAddress2();

注:GetProcAddress函数可以通过序号值来指定函数,也可以通过函数名称来指定函数(这种情况在生成DLL时,需要.def模版定义文件,把需要导出的函数名称写入.def文件中)。两种情况的比较如下图中所示:

分享到:
评论

相关推荐

    查看 dll 导出函数 的小工具

    "查看dll导出函数"这个小工具就是专门用来帮助开发者和系统管理员查看DLL文件所包含的可供外部调用的函数列表。 DLL导出函数的查看通常涉及到以下几个知识点: 1. **DLL导出**:DLL导出是将函数公开给其他模块使用...

    查看DLL 导出函数

    查看DLL导出函数是理解DLL功能的关键步骤,这对于程序开发、调试和逆向工程尤其重要。下面将详细介绍如何查看DLL的导出函数以及相关知识。 首先,DLL文件在Windows系统中主要用来实现代码重用和模块化设计。当一个...

    x64位DLL接口导出函数查看器

    “x64位DLL接口导出函数查看器”就是这样一个工具,它能够帮助开发者和系统管理员查看64位DLL文件中包含的所有导出函数,这对于调试、分析和优化程序至关重要。通过该工具,用户可以: 1. **查看函数列表**:列出...

    函数查看器 用于查看dll里导出函数

    查看动态链接库DLL文件接口函数信息.DLL函数查看器V2.0是在1.0版的基础上作了重大的改进,不仅支持查看DLL文件的导出函数和引用函数信息及引用函数来源,也支持所有符合PE文件格式的文件,包括EXE文件、OCX文件等的导出...

    查看dll中导出函数的工具

    总之,"查看dll中导出函数的工具"是软件开发和逆向工程过程中的实用辅助工具,通过提供深入的DLL分析能力,它可以帮助开发者更好地理解和利用DLL资源,提高工作效率。对于任何涉及DLL工作的程序员来说,掌握这类工具...

    查看dll导出函数的小程序(英文版)

    本压缩包中的"查看dll导出函数的小程序(英文版)"是一个实用工具,专门设计用于查看DLL文件中导出的函数详情。 DLL的导出函数是DLL对外提供的接口,其他程序通过这些函数名来调用DLL中的功能。了解一个DLL的导出函数...

    DLL Export Viewer v1.45 x64,查看DLL导出函数的工具

    DLL(Dynamic Link Library)是Windows操作系统中的一个重要组件,它是一种可重用的代码库,包含了一组函数和资源,可供多个程序共享使用。DLL Export Viewer 是一个实用工具,特别是对于软件开发者和系统管理员来说...

    新版绿色depends看DLL导出函数

    depends是Windows系统下的一款实用工具,它可以分析并显示DLL文件中的导出函数和它们所依赖的其他DLL。通过这个工具,开发者可以了解一个程序在运行时需要哪些DLL文件,以及这些DLL提供的功能。新版绿色depends更...

    DLL导出函数查看器1.5

    DLL导出函数查看器1.5是一款实用工具,专门用于查看和分析DLL文件中的导出函数,这对于软件开发、调试以及系统维护人员来说极其有价值。 在Windows编程中,DLL的作用主要体现在以下几个方面: 1. **代码复用**:DLL...

    VC++编写DLL导出函数及其调用方法

    在Windows编程环境中,动态链接库(DLL)是一种可重用代码的共享库,它包含一组可供其他应用程序调用的函数和资源。本教程将详细讲解如何使用VC++(以Visual Studio 2008 SP1为例)来创建、编写和导出DLL,以及如何...

    Depends C++DLL导出函数查看器

    Depends是一个的实用工具,扫描任何32位或64位Windows模块( EXE文件, DLL的,控件,系统等) ,并建立所有相关...可以查看C++导出DLL的导出函数信息,同时也可以查看EXE文件的依赖关系,是C++\C#开发人员必备工具。

    DLL查看器,查看dll导出函数

    在DLL查看器中,用户可以清晰地看到每个导出函数的名称,这对于理解和使用DLL至关重要。通过查看这些函数名,开发者可以判断DLL是否包含所需的功能,或者分析DLL与其它程序的交互方式。 其次,DLL查看器还可能提供...

    DLL导出类的三种方法,导出接口类,导出类指针,导出类,不建议使用导出类

    本篇将详细讲解DLL导出类的三种常见方法:导出接口类、导出类指针以及导出类,并说明为什么通常不建议直接导出类。 1. 导出接口类 接口类(Interface Class)是一种只包含纯虚函数的抽象基类,不包含任何数据成员...

    从dll中导出函数

    ### 从DLL中导出函数 #### 一、概述 动态链接库(Dynamic Link Library,简称DLL)是Windows操作系统中的一个重要组成部分,它允许程序共享代码和其他资源。在软件开发过程中,经常需要创建自定义的DLL,并从中...

    DLL导出函数查看工具

    "DLL导出函数查看工具"是一款专为IA-64(Itanium架构)平台设计的实用程序,它帮助开发者查看和分析DLL文件中的导出函数。 IA-64架构是一种64位微处理器架构,由Intel公司设计,主要应用于高性能服务器和工作站领域...

    DLL导出函数查看器(专用工具)

    DLL导出函数查看器是一款专门设计用于查看DLL文件中导出函数的专业工具,对于软件开发、调试和系统维护人员来说,它是一个不可或缺的辅助工具。 首先,我们要理解DLL的导出函数。在DLL中,可以定义一些函数,并声明...

    dllexp DLL导出函数查看器

    本文将通过介绍"dllexp DLL导出函数查看器"这一工具,深入探讨DLL的核心概念——导出函数,以及如何利用该工具进行分析和调试。 首先,我们要理解DLL的基本功能。DLL文件中包含了可执行代码和数据,它们可以在运行...

    DLL导出函数查看器1.5.rar

    总之,“DLL导出函数查看器1.5”是一款DLL开发者的必备工具,它通过提供详尽的DLL导出函数信息,极大地简化了DLL的开发和调试过程。无论是新手还是经验丰富的开发者,都能从中受益,提升工作效率,确保项目的顺利...

    VC6.0实现查看dll导出函数名源码

    使用VC6.0实现查看dll导出函数名的C++源代码,供参考。

    MFC 扩展DLL(导出类)

    导出函数和类** 为了使DLL中的类和函数可被外部程序使用,你需要使用`__declspec(dllexport)`或`__declspec(dllimport)`来控制导出。在DLL的源代码中,使用`__declspec(dllexport)`,而在使用DLL的客户端代码中,...

Global site tag (gtag.js) - Google Analytics