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

    安装mingw一直安装不成功 用TDM-GCC方便多了 附链接http://tdm-gcc.tdragon.net/

  2. Codeforces Round #284 (Div. 2)A B C 模拟 数学

    A. Watching a movie time limit per test 1 second memory limit per test 256 megabytes input standard ...

  3. study java language

    2016.11.30 1).About the Java Technology 2).The Java Language Environment: Contents

  4. JS和Android交互

    //本地webview写法 webview = (WebView) findViewById(R.id.webview); webview.loadUrl("http://192.168.1 ...

  5. POJ 1014 Dividing

    Dividing Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 66032 Accepted: 17182 Descriptio ...

  6. 开始写Effective系列总结一些前端的心得

    确实是没有时间整理以及总结和发表自己的感慨.难得中秋银行的事情搞完了自己清闲3天,是时候总结一下从大公司做.NET PC 端网站的开发到现在做移动互联网的银行及政府微信公众号的开发的感触.当时自己的选 ...

  7. 多模块打包后,扫描不到@controller和@service,实现 ADD DIRECTORY ENTRIES

    多模块打包后,扫描不到@controller和@service等Bean. 原因:打包时没有生成目录信息 解决办法: 1.在eclipse或者myeclipse 打包时 勾选 ADD DIRECTOR ...

  8. .lib文件 .h文件 .dll文件

    .lib代表的是静态数据连接库,在windows系统中起到链接程序和函数的作用,存放的是函数的是函数调用的信息,是obj文件的集合.相当于linux中的.a或.0. .so文件.lib文件是不对外公开 ...

  9. 3-HOP: A High-Compression Indexing Scheme for Reachability Query

    title: 3-HOP: A High-Compression Indexing Scheme for Reachability Query venue: SIGMOD'09 author: Ruo ...

  10. 注册noip.com动态域名的步骤

    1.先打开这个网址 http://www.noip.com/ 2.点击页面右上绿色的Sing Up,进行注册 3.会出现这个页面,把这些填上 Create my hostname later这一项不打 ...