Windows动态库学习心得
最近在工作中需要给项目组其他成员提供调用函数,决心抛弃以前“拷贝头文件/源文件”的简陋方法,采用动态库的方式对自己开发的接口进行模块化管理。因之前一直没有机会从事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进行动态库的运行时加载:
- LoadLibrary——装载一个DLL到进程的地址空间;
- GetProcAddress——查找某个符号(函数)的地址;
- 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动态库学习心得的更多相关文章
- 【转】分析Linux和windows动态库
原文地址:http://www.cnblogs.com/chio/archive/2008/11/13/1333119.html 摘要:动态链接库技术实现和设计程序常用的技术,在Windows和Lin ...
- Linux和windows动态库
转载:http://www.cnblogs.com/chio/archive/2008/11/13/1333119.html 态链接库技术实现和设计程序常用的技术,在Windows和Linux系 统中 ...
- windows动态库与Linux动态库
Linux动态库和windows动态库的目的是基本一致的,但由于操作系统的不同,他们在许多方面还是不尽相同.但是尽管有差异Linux动态库的windows动态库还是可以移植的,有一些规则以及经验是必须 ...
- linux和windows动态库加载路径区别
# linux和windows动态库加载路径区别 ### 简介------------------------------ linux加载动态库的路径是系统目录/lib和/usr/lib.- wind ...
- Windows 动态库创建和使用 part 2
一.Windows动态库的创建: 1.先选择 "DLL" 和 “控项目” 2.添加一个头文件,一个源文件 CppDll.h,CppDll.cpp,一个模块定义文件 CppDll. ...
- windows类书的学习心得(转载)
原文网址:http://www.blogjava.net/sound/archive/2008/08/21/40499.html 现在的计算机图书发展的可真快,很久没去书店,昨日去了一下,真是感叹万千 ...
- windows类书的学习心得
原文网址:http://www.blogjava.net/sound/archive/2008/08/21/40499.html 现在的计算机图书发展的可真快,很久没去书店,昨日去了一下,真是感叹万千 ...
- windows 动态库的封装以及调用
1.一个程序从源文件编译生成可执行文件的步骤:预编译 --> 编译 --> 汇编 --> 链接(1)预编译,即预处理,主要处理在源代码文件中以“#”开始的预编译指令,如宏展开.处 ...
- Windows动态库的使用 part one
二.动态库程序 这篇写得比较乱,看不懂的可以跳part 2,直接上图片的. 动态库的使用: 4.3.1 隐式链接 动态库的隐式连接,需要动态库的 动态库文件".dll" , 动 ...
随机推荐
- 【转】oracle内存分配和调优总结
转自 http://blog.itpub.net/12272958/viewspace-696834/ 一直都想总结一下oracle内存调整方面的知识,最近正好优化一个数据库内存参数,查找一些资料并且 ...
- Java笔记8-抽象接口
高级特性部分: 抽象(abstract) 接口(interface) 提纲: 抽象类的定义和使用 模板设计模式的使用 接口的定义和使用 回调函数 区别抽象类和接口的异同 软件设计原则--------- ...
- fail to create java virtual machine..
今天打开zend stdio 的时候 出现的错误 fail to create java virtual machine... 然后找度娘了,,都说改xxxxx, 我打开360 ,把内存清理了一遍 ...
- IOS 二维码的实现
1.首先导入Coreimage框架. //创建滤镜对象 CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator&quo ...
- CSS实现垂直居中的5种方法
利用 CSS 来实现对象的垂直居中有许多不同的方法,比较难的是选择那个正确的方法.我下面说明一下我看到的好的方法和怎么来创建一个好的居中网站. 使用 CSS 实现垂直居中并不容易.有些方法在一些浏览器 ...
- ASP.NET Core (Database First)
CREATE DATABASE [EFCore_dbfirst] GO USE [EFCore_dbfirst] GO CREATE TABLE [Blog] ( [BlogId] int NOT N ...
- 关于unity中C#使用WaitForSeconds的方法
//我有一段这样的代码,我要实现3秒后执行内容,JS是这样写的 function Update () { load (); } function load (){ //等待3秒执行语句 yield W ...
- Tomcat报错:Failed to start component [StandardEngine[Catalina].StandardHost[localhost]]
Failed to start component [StandardEngine[Catalina].StandardHost[localhost]] 解决办法: 1,检测你的web.xml.去掉所 ...
- DNS学习笔记之DNS理论知识
DNS: Domain Name System (将域名和ip地址相互转化) 域名是一个范围,例如baidu.com,.com.而www.baidu.com是个主机名,即FQDN: Full Qual ...
- 自定cordova插件笔记demo
1.在项目根目录下(我的是com.chl),添加一个文件夹,在文件夹里添加src.www两个子文件夹和plugin.xml文件.在www目录下,创建test.js.在src文件夹下添加android子 ...