最近在工作中需要给项目组其他成员提供调用函数,决心抛弃以前“拷贝头文件/源文件”的简陋方法,采用动态库的方式对自己开发的接口进行模块化管理。因之前一直没有机会从事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. jsp和servlet中文乱码

    jsp和servlet之间出现中文乱码的集中原因和解决方法详解:http://blog.csdn.net/longyuhome/article/details/7856270

  2. LeakCanary Android 和 Java 内存泄露检测。

    开始使用 在 build.gradle 中加入引用,不同的编译使用不同的引用: dependencies { debugCompile 'com.squareup.leakcanary:leakcan ...

  3. CentOS7 搭建python3 Django环境

    yum install gcc yum install make yum install openssl-devel -y yum install sqlite-devel -y wget https ...

  4. Linux达人养成第一季

    Linux简介 一.Linux发展史 二.开源软件简介 三.Linux应用领域 四.Linux学习方法 五.Linux与Windows的不同 六.字符界面的优势 Linux系统安装 一.虚拟机安装 二 ...

  5. outscan 一键批量 get struct2 devMode (CNVD-2016-04656)

    之前写的一个玩意 下载地址:http://pan.baidu.com/s/1i5jmEwP 密码:v8v3 一键批量 get struct2 devMode 支持百度.google(google有访问 ...

  6. while 循环

    while(condition) { //........ } 循环在我们从事C语言开发的过程中可以说用的挺多的,但是今天想起了一个问题,源于我要在一个长字符串中查找特定字符串,于是我写了如下代码: ...

  7. 转:linux lsof命令详解

    简介 lsof(list open files)是一个列出当前系统打开文件的工具.在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件.所以如传输控 ...

  8. git下载自己项目到本地

    git下载自己项目到本地 假如外出工作,需要在另一台电脑上面pull自己的某个git远程项目到本地 $ git init $ git pull https://github.com/TTyb/54qj ...

  9. 浅入浅出“服务器推送”之一:Comet简介

    最近有个项目,其中有项需求要从服务器端主动向客户端推送数据,本以为很简单,但在实际做的过程中发现很棘手,并没有想象中的简单.从网上搜索学习,发现主流讲的还是Ajax的长轮询技术或者流技术,websoc ...

  10. winform基本控件的使用2(用户登录界面的设计)

    首先还是通过例子来讲解,这次的实验主要是使用messageBox的使用方法,关于messageBox的使用方法在我的博客里面有相关的转载,请自己查看,下面说一下实验要求. 功能要求:模拟一个用户登陆的 ...