最近在工作中需要给项目组其他成员提供调用函数,决心抛弃以前“拷贝头文件/源文件”的简陋方法,采用动态库的方式对自己开发的接口进行模块化管理。因之前一直没有机会从事Windows动态库的开发,现借助这个开发任务,恶补了《程序员的自我修养》这本书,并通过动手实践+上网找资料的方式,学习了Windows DLL的工作原理、常见用法。本篇分为4个部分:DLL实例演示;DLL显示运行时链接;符号导入导出表;DLL优化。

1、DLL实例演示

(a)创建一个简单的DLL

  • 编写代码
_declspec(dllexport) double Add(double a, double b)
{ return a + b;
} _declspec(dllexport) double Sub(double a, double b)
{ return a- b;
} _declspec(dllexport) double Mul(double a, double b)
{
return a * b;
}
  • 使用MSVC的编译器CL进行编译

  

(b)创建测试程序,使用DLL

  • 编写代码
#include <stdio.h>

_declspec(dllimport) double Sub(double a, double b);

void main()
{
double result = Sub(3.0,2.0);
printf("Result = %f\n",result);
}
  • 进行编译、链接、执行

(c)使用模块定义文件生成DLL

  • 修改代码,去除_declspec(dllexport):
double Add(double a, double b)
{ return a + b;
} double Sub(double a, double b)
{ return a- b;
} double Mul(double a, double b)
{
return a * b;
}
  • 编写模块定义文件Math.def
LIBRARY Math

EXPORTS

Add
Sub
Mul
  • 重新编译Math.c文件

  • 重新链接TestMath.obj和Math.lib——link TestMath.obj Math.lib

2、DLL显示运行时链接

  Windows中提供3个API进行动态库的运行时加载:

    1. LoadLibrary——装载一个DLL到进程的地址空间;
    2. GetProcAddress——查找某个符号(函数)的地址;
    3. FreeLibrary——卸载装载到进程中的DLL。
  • 编写代码
#include <windows.h>
#include <stdio.h> /*
* Description: 申明一个函数指针,要求其输入两个double数据,返回一个double
*/
typedef double (*Func)(double,double); void main()
{
Func function;
double result; //加载动态库
HINSTANCE hinstLib = LoadLibrary("Math.dll");
if (hinstLib == NULL)
{
printf("错误:不能加载动态库\n");
return;
} //获取动态库中函数地址
function = (Func)GetProcAddress(hinstLib,"Add");
if (function == NULL)
{
printf("错误:不能找到Add函数\n");
//出错调用,需释放动态库
FreeLibrary(hinstLib);
return;
} //执行动态库函数
result = function(1.0,2.0); //出错调用,需释放动态库
FreeLibrary(hinstLib); //显示结果
printf("Result=%f\n",result);
}
  • 编译,执行

3、符号导入导出表

1、打开Microsoft Visual C++6.0 Tools——>Depends,将生成的Math.dll拖入其中,便可以查看动态库导出的函数

2、使用dumpbin,根据参数/EXPORTS,显示导出函数表

3、使用dumpbin,根据参数/IMPORTS,显示导入函数表

4、DLL优化

  导入函数绑定——如果程序运行时,其依赖的DLL都以同样的顺序装载到同样的内存地址,那么他们的导出符号的地址是不变的。因此可以考虑将这些导出函数的地址保存至执行程序的导入表中,这样程序每次启动时都可以省去符号解析的过程。

  • 使用工具editbin对TestMath.exea进行绑定:

  • 查看绑定后TestMath.exe的导入表:

Windows动态库学习心得的更多相关文章

  1. 【转】分析Linux和windows动态库

    原文地址:http://www.cnblogs.com/chio/archive/2008/11/13/1333119.html 摘要:动态链接库技术实现和设计程序常用的技术,在Windows和Lin ...

  2. Linux和windows动态库

    转载:http://www.cnblogs.com/chio/archive/2008/11/13/1333119.html 态链接库技术实现和设计程序常用的技术,在Windows和Linux系 统中 ...

  3. windows动态库与Linux动态库

    Linux动态库和windows动态库的目的是基本一致的,但由于操作系统的不同,他们在许多方面还是不尽相同.但是尽管有差异Linux动态库的windows动态库还是可以移植的,有一些规则以及经验是必须 ...

  4. linux和windows动态库加载路径区别

    # linux和windows动态库加载路径区别 ### 简介------------------------------ linux加载动态库的路径是系统目录/lib和/usr/lib.- wind ...

  5. Windows 动态库创建和使用 part 2

    一.Windows动态库的创建: 1.先选择 "DLL" 和 “控项目” 2.添加一个头文件,一个源文件  CppDll.h,CppDll.cpp,一个模块定义文件 CppDll. ...

  6. windows类书的学习心得(转载)

    原文网址:http://www.blogjava.net/sound/archive/2008/08/21/40499.html 现在的计算机图书发展的可真快,很久没去书店,昨日去了一下,真是感叹万千 ...

  7. windows类书的学习心得

    原文网址:http://www.blogjava.net/sound/archive/2008/08/21/40499.html 现在的计算机图书发展的可真快,很久没去书店,昨日去了一下,真是感叹万千 ...

  8. windows 动态库的封装以及调用

    1.一个程序从源文件编译生成可执行文件的步骤:预编译 -->  编译 -->  汇编 --> 链接(1)预编译,即预处理,主要处理在源代码文件中以“#”开始的预编译指令,如宏展开.处 ...

  9. Windows动态库的使用 part one

    二.动态库程序 这篇写得比较乱,看不懂的可以跳part 2,直接上图片的.   动态库的使用: 4.3.1 隐式链接 动态库的隐式连接,需要动态库的 动态库文件".dll" , 动 ...

随机推荐

  1. android 底层开发入门(一)

    第一个Linux驱动程序:统计单词个数 一.首先了解一下: 打印机驱动写入数据:对于打印机驱动来说,需要接收这些被写入的数据,并将它们通过PC的并口.USB等端口发送给打印机.要实现这一过程就需要Li ...

  2. Codeforces Round #175 (Div. 2)

    A. Slightly Decreasing Permutations 后\(k\)个倒序放前面,前\(n-k\)个顺序放后面. B. Find Marble 模拟. C. Building Perm ...

  3. code forces 382 D Taxes(数论--哥德巴赫猜想)

    Taxes time limit per test 2 seconds memory limit per test 256 megabytes input standard input output ...

  4. linux创建动态库

    [1]新建源程序sharelib.c /************************************************************************* > F ...

  5. 关于vue.js中表单控件绑定练习

    html: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8 ...

  6. sass编译

    sass编译 命令行编译 单文件转换命令 sass style.scss style.css 单文件监听命令 sass --watch style.scss:style.css 文件夹监听命令 sas ...

  7. Windows快速删除文件脚本

    1.新建一个txt文件 2.将DEL /F /A /Q \\?\%1RD /S /Q \\?\%1这段代码放在新建好的txt文件中 3.将txt文件的后缀名改为.bat 4.将这个文件放在需要删除的文 ...

  8. css3 animation实现风车转动

    项目中经常有用到动画效果,比如Loading.风车转动等等.最简单的办法是使用gif,但是gif在半透明背景下有白边,体验不友好,好在现在可以使用css3的anmiation来实现动画效果,极大的提升 ...

  9. mysql if case条件更新

    在mysql中,如果你要根据某个字段的值不一样,来更新另一个字段的值,可以用如下sql语句: 如果仅仅是两个分支,if语句就可以了 update tm set page_name=if(q_aswer ...

  10. 【转】关于启用 HTTPS 的一些经验分享

    随着国内网络环境的持续恶化,各种篡改和劫持层出不穷,越来越多的网站选择了全站 HTTPS.HTTPS 通过 TLS 层和证书机制提供了内容加密.身份认证和数据完整性三大功能,可以有效防止数据被查看或篡 ...