dll--二进制层面的复用
积木式思想其实是很自然的一个过程,从c的库函数到C++的标准库,再到dll、com、com+都是这种思想推动下的结果,和现实生活中的人们的思维方式并无二致,只不过软件是在一个虚拟的世界中,并分化出许多不同的形式。
二进制层面的复用主要是依赖于现代loader提供的强大能力,它使得二进制的功能块(dll,exe,sys,ocx...)可以在内存中组合成一个相互合作的系统,也就是我们常说的动态链接(相对于静态链接在编译时期形成一个单一的文件)。
剩下的问题就是怎么合作的问题了,导入导出函数就是功能块之间互联互通的一个窗口,包括com不管理论多么复杂高深多么封装,也离不开导出函数,二进制复用看来是软件工程中一种终极的复用方式了。
c++中允许函数重载,对此c++实际上并不去根据参数决定调用哪个函数,而是直接给重载函数取不同的名称(mangling mechanism),导出的时候也是导出这些被mangled的名字 ,除非该函数声明为c方式处理,则函数名称不会被二次加工。
编译dll时会附带一个lib文件,包含了dll的导出函数表,导入程序中可以包含该lib文件以及相应的头文件,使用时和使用未编译的源码一样,也可以使用loadlibrary 和getprocaddress在运行时使用dll提供的功能,这里getprocaddress时需要注意的是,如果dll只导出了函数的ordinal,那么需要用makentresource(ordinal)做一下转换,getprocaddress会根据这个ordinal在导出表中找到对应的函数地址。
为了保持导入程序中使用的函数名称和dll导出的函数名称一致(这样可以保证根据name在导出表中找到对应的函数地址),如果dll中使用了extern "C"方式处理函数,那么导入函数中也要使用extern "C"方式处理相应函数声明,否则名称不会一致,如果使用了extern "C" 后函数前加上__stdcall声明,那么name mangling mechanism 又被激活,实际上得出的函数名称还是C++风格的名称。还有一种保持一致的方式是在生成dll时用def文件对导出的函数名称进行说明,例如:
LIBRARY DLL1
EXPORTS
add//函数名称不被转换
subtract
inc=increase//原始名称专成目标名称
sub=subb
abc @1//对应的ordinal
cde @2
ps:
1.dll中有数据段和代码段,代码段在内存中只有一份,为多个进程共享,数据段默认都是进程私有的,这个操作系统在做内存页映射的时候会处理,数据段也可以被声明为共享的,用于进程间通信,但这样可能导致恶意进程非法改动共享数据,破坏其他进程。声明方法(http://blog.csdn.net/xuplus/article/details/2291860)
2.lib文件有两种1.用于静态连接,包括声明和实现2.用于动态连接,只包括声明,相当于一个头文件,lib文件的格式和.a(archive)文件格式类似,都是一些coff obj文件的集合。
3.extern等同于__declspec(dllimport)
4.dll中类的导出实际上是类的成员函数的导出,其中包括构造函数(or 系统默认构造函数),当然也可以部分导出类成员函数(如果你的导入程序中没有用到其他成员函数的话),类的数据成员都是在导入程序的空间中。
dll--二进制层面的复用的更多相关文章
- C++设计模式 之 “组件协作”模式:Template Method、Strategy、Observer
“组件协作”模式: #现代软件专业分工之后的第一个结果是“框架与应用程序的划分”,“组件协作”模式通过晚期绑定,来实现框架与应用程序之间的松耦合,是二者之间协作时常用的模式. #典型模式: Templ ...
- 在C++中调用DLL中的函数 (3)
1.dll的优点 代码复用是提高软件开发效率的重要途径.一般而言,只要某部分代码具有通用性,就可将它构造成相对独立的功能模块并在之后的项目中重复使用.比较常见的例子是各种应用程序框架,ATL.MFC等 ...
- com和dll(一)
1.com为一种规范,使不同语言能在二进制层面上进行交互. 2.dll为ms的一种程序打包文件,使程序的代码能分开打包编译,并能在运行时共享.
- DLL模块:C++在VS下创建、调用dll
1.dll的优点 代码复用是提高软件开发效率的重要途径.一般而言,只要某部分代码具有通用性,就可将它构造成相对独立的功能模块并在之后的项目中重复使用.比较常见的例子是各种应用程序框架,ATL.MFC等 ...
- .NET Core跨平台的奥秘[中篇]:复用之殇
在<.NET Core跨平台的奥秘[上篇]:历史的枷锁>中我们谈到:由于.NET是建立在CLI这一标准的规范之上,所以它天生就具有了"跨平台"的基因.在微软发布了第一个 ...
- 在C++中调用DLL中的函数(3)
1.dll的优点 代码复用是提高软件开发效率的重要途径.一般而言,只要某部分代码具有通用性,就可将它构造成相对独立的功能模块并在之后的项目中重复使用.比较常见的例子是各种应用程序框架,ATL.MFC等 ...
- C++在VS下创建、调用dll
转自:http://www.cnblogs.com/houkai/archive/2013/06/05/3119513.html 目录 1.dll的优点 代码复用是提高软件开发效率的重要途径.一般而言 ...
- DLL导出类避免地狱问题的完美解决方案
DLL动态链接库是程序复用的重要方式,DLL可以导出函数,使函数被多个程序复用,DLL中的函数实现可以被修改而无需重新编译和连接使用该DLL的应用程序.作为一名面向对象的程序员,希望DLL可以导出类, ...
- Objective-C 里面的类对象复用小结
OC 提供了单继承 (Inheritance), Category, Extension, Protocol 这几种基本的类与对象层面的复用机制,作一小结. 在这几个机制中,继承提供了纵向的复用,可以 ...
随机推荐
- 解决办法-错误:Access denied for user 'root'@'localhost' - java
如下更改密码即可 mysql> UPDATE user SET Password=PASSWORD('newpassword') where USER='root';mysql> FLUS ...
- php生成图片
//生成图片,第一个参数宽,第二个高 1.$image = imagecreatetruecolor(100,25); //生成颜色,当第一次调用生成颜色的方法,是生成背景颜色 2.$backgrou ...
- MVC(模型-视图-控制器)的理解
在 MVC 中,模型对象表示数据(例如日历应用程序中的待办事项或绘图程序中的图形),视图对象知道如何显示模型对象所表示的数据,控制器对象充当模型和视图的媒介.在“HelloWorld”应用程序中,模型 ...
- Linux怎么使用添加的新硬盘
一.磁盘分区 装过系统后第一块磁盘的设备号是/dev/sda,在你添加一个新的磁盘后一般情况下是/dev/sdb *******进入fdisk界面***** # fdisk /dev/sdbDevic ...
- Mac OS环境变量配置(Android Studio之Gradle)
以gradle环境变量配置为例: Android Studio 自带的gradle路径为: /Applications/Android\ Studio.app/Contents/gradle/grad ...
- GIT之二 基础篇(2)
远程仓库的使用 要参与任何一个 Git 项目的协作,必须要了解该如何管理远程仓库.远程仓库是指托管在网络上的项目仓库,可能会有好多个,其中有些你只能读,另外有些可以写.同他人协作开发某个项目时,需要管 ...
- JLOI 提示问题
按照题目意思模拟即可. Program XJOI2265; ..] of char=('a','e','i','o','u','A','E','I','O','U'); var s:ansistrin ...
- 数据库 SQL优化
1.对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...
- 使用Inno Setup 打包.NET程序,并自动安装.Net Framework
使用Inno Setup 打包.NET程序,并自动安装.Net Framework http://www.cnblogs.com/xiaogangqq123/archive/2012/03/19/24 ...
- NSData和NSString 、 NSFileManager
1 NSData和NSMutableData的基本使用 1.1 问题 NSData类是IOS提供的用于以二进制的形式操作文件数据的类,NSData有两个常用的属性length和bytes,length ...