b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

动态链接库(dll)文件分析

电脑杂谈  发布时间:2020-06-27 04:24:12  来源:网络整理

dll文件_wsock32.dll文件_怎么写dll文件

1. 使用VS生成动态链接库的步骤:

(1)创建一个新的win32控制台项目,并在应用程序设置窗口中选择“ Dll”选项,然后选择“ Empty Project”作为附加选项. 如下图所示:

这里写图片描述

(2)创建项目后,添加源文件,并将要导出的功能写入源文件中的dll文件. 应该在函数声明之前添加“ _Declpec(dllexport)”,以指示函数输出是动态链接库. 另外,必须在函数名称的前面添加调用约定. 因为c / c ++语言的默认调用约定为“ _cdecl”,所以如果使用“ _cdecl”调用约定,则无需编写它. 如果使用“ _stdcall”和“ _fastcall”调用约定,则需要进行解释. 下图是一个简单的示例:

这里写图片描述

图中有三个函数,并且使用的调用约定为“ _cdecl”,“ _ stdcall”和“ _fastcall”. 调用约定将为函数名称添加一些修饰. 不同的调用约定对函数名的修改也不同,因此请谨慎使用调用约定.

(3)编译. 单击菜单栏“生成”中的“生成解决方案”以生成动态链接库. 如果编译成功,则可以在项目文件夹下的Debug文件夹中找到带有后缀dll和lib的文件. 其中,lib文件包含函数的相关定义和索引,其作用类似于头文件,dll文件是函数的实现部分,缺一不可.

2. 生成动态链接库时需要注意的事项

(1)以“ _declspec(dllexport)”开头的函数声明指示该函数将作为动态链接库输出,这是必不可少的,

dll文件_wsock32.dll文件_怎么写dll文件

(2)如果导出的函数不使用C / C ++默认的“ _cdecl”调用约定,则需要特殊说明. 使用调用约定时,应考虑将来调用函数的问题. 调用时使用的调用约定只有在与生成时设置的调用约定一致时才能调用. 换句话说,如果在生成dll文件时为函数设置的调用约定为“ _stdcall”,而在调用函数时使用的调用约定为“ _cdecl”,则找不到该函数.

(3)在相同的调用约定下,使用不同的编译器,对函数名称的修改是不同的. 例如,使用相同的“ _cdecl”调用约定. 在C语言和C ++语言导出的dll文件中,函数的修改名称不同. 如果要使用C样式的dll文件,则需要添加“ extern C”进行修改,或将源文件名的后缀更改为.c. 如果它是C ++样式的dll文件,则源文件名后缀必须为.cpp. 下图是生成C样式dll文件的示例:

这里写图片描述

前两个函数将导出为C风格的dll,后一个函数将导出为C ++风格的dll. 如果将源文件后缀更改为.c,则所有功能都将导出为C样式的dll.

1. C语言调用C语言dll文件

如图所示,有3个函数导出到dll,前两个是C语言样式,后一个是C ++样式. C语言无法使用常规方法调用C ++风格的dll.

这里写图片描述

(1)创建一个新的控制台项目,添加一个源文件,并将源文件的后缀更改为.c,以告知编译器这是C语言程序.

(2)将lib文件和dll文件与源文件放在同一目录中.

wsock32.dll文件_dll文件_怎么写dll文件

(3)在程序开头添加#pragma注释(lib怎么写dll文件,“ mydll.lib”). 第一个参数必须是lib,第二个参数是lib文件的文件名. 必须在调用函数之前声明它. 该函数的声明需要用调用约定修饰. 如下图所示:

这里写图片描述

(4)生成解决方案. 如果没有错误,运行程序将输出正确的结果.

2. C ++调用C语言dll

在C ++程序中,要调用C语言dll,必须声明被调用函数是C语言样式. 该方法是在函数声明中添加extern“ C”. 创建一个新的控制台项目,添加一个cpp文件,源文件中的代码如图所示:

这里写图片描述

3. C ++调用C ++ dll

C ++调用C ++ dll,只需要在函数声明中添加调用约定. 如下图所示:

这里写图片描述

wsock32.dll文件_怎么写dll文件_dll文件

4. 动态加载dll

上述调用dll的方法都是静态调用类型,通常需要lib文件. 如果使用动态加载dll,则不需要lib文件,仅dll文件就足够了. 动态加载dll需要两个函数,一个是LoadLibrary,另一个是GetProcAddress. 这两个函数都包含在window.h头文件中. 值得注意的是,动态加载dll文件的方法通常只能使用“ _cdecl”的调用约定来调用C样式的函数. 下图是动态加载dll的示例:

这里写图片描述

如上所述,动态加载dll的方法通常适合于使用“ _cdecl”的调用约定来调用C样式的函数. 这是因为调用约定为“ _cdecl”的C样式函数的函数名称将不是“修改”,源文件的外观以及dll文件中的外观. 当然,也可以调用非“ _cdecl”约定的C ++样式函数,但这很麻烦. 因为编译器类型(C或C ++)和调用约定都修改了函数名,所以dll文件中的函数名不再写在源文件中. GetProcAddress函数通过函数名称查找函数条目. 因此,只要您知道dll文件中的函数修改名称并将该函数修改名称传递给GetProcAddress函数,就可以获取函数指针. 那么怎么写dll文件,您如何知道dll文件中函数的修饰名称?这需要使用某些分析软件,例如依靠该软件来查看dll文件的功能名称. 下图是使用依赖软件来查看dll中的功能. 您可以看到dll文件中“添加”和“”功能的修改名称是?Add @@ YGHHH @ Z和?Multi @@ YGHHH @ Z.

这里写图片描述

所有函数都可以通过在dll文件中查找修饰的名称来获取函数指针吗?为此,我做了一些实验,这个实验可能还不够,但是还可以得出一些结论:

(1)将dll中函数的修改名称传递给GetProcAddress函数. 如果dll中的函数使用“ _cdecl”调用约定,则无论是C样式还是C ++样式,都不会报告错误,并且该函数调用的结果也正确. 下图是使用“ _cdecl”调用约定的调用函数:

这里写图片描述

这里写图片描述

怎么写dll文件_wsock32.dll文件_dll文件

从实验结果来看,只要具有调用约定“ _cdecl”的函数可以通过depends找到该函数的修饰名称,就可以调用该函数. 函数调用的结果正确.

(2)将dll中函数的修改名称传递给GetProcAddress函数. 如果dll中的函数使用“ _stdcall”调用约定,则在程序运行时将报告一个错误,但该错误将被忽略,并且调用的结果是正确的. 下图显示了名为“ _stdcall”的函数:

这里写图片描述

这里写图片描述

根据实验结果,调用“ _stdcall”约定的函数将报告错误,但结果仍然正确.

(3)将dll中函数的修改名称传递给GetProcAddress函数. 如果dll中的函数使用“ _fastcall”调用约定,则该程序将不会报告错误,但是调用结果是错误的!下图显示了名为“ _fastcall”的函数:

这里写图片描述

这里写图片描述

非常令人沮丧的是,当调用“ _fastcall”函数时,程序在运行时不会报告错误,但是调用的结果是非常可笑的. 2 + 3 = -1672607445这到底是什么?原因不明.

(4)结论: 通过使用LoadLibrary函数和GetProcAddress函数动态加载dll文件,此方法仅适用于调用“ _cedcl”约定的函数,只要采用“ _cdecl”约定,可以正常调用C风格还是C ++风格. 如果是其他调用约定,则不能正常调用C样式或C ++样式的函数.


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-259864-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...