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 这几种基本的类与对象层面的复用机制,作一小结. 在这几个机制中,继承提供了纵向的复用,可以 ...
随机推荐
- Spark的编译
由于Spark的运行环境的多样性,如可以运行在hadoop的yarn上,这样就必须要对Spark的源码进行编译.下面介绍一下Spark源码编译的详细步骤: 1.Spark的编译方式:编译的方式可以参考 ...
- poj1141 区间dp+路径
//Accepted 176 KB 47 ms //感谢大神们为我们这群渣渣铺平前进的道路!! //用scanf("%s",s)!=EOF WA到死 #include <cs ...
- 让一个小Div(子)在大Div(父)中垂直水平都居中
方法1: .parent { width:800px; height:500px; border:2px solid #000; ...
- M1-S70卡片介绍
卡片有4K的存储空间,有32个小扇区和8个大扇区.小扇区的结构为:每扇区有4块,每块16个字节,一共64字节,第3块为密钥和控制字节:大扇区的结构为:每扇区16块,每块16个字节,一共256字节,第1 ...
- 原生javascript Ajax
代码 1. IE5 ,IE6 使用ActiveXObject对象, 其余现代浏览器都支持XMLHttpRequest对象: function ajaxObject(){ var xmlhttp; ...
- Python 第三方模块安装出现的问题和解决方案.
出现此类问题 A) ImportError: cannot import name '_win32stdio'B) ImportError: No module named 'win32api' 需要 ...
- eclipse GIT使用
新建工程(要和GIT上同名,同类型)->右键->team->add to index->commit->更新config文件->remote: fetch from ...
- 程序员是怎么炼成的---OC题集--练习答案与题目(1)
一. 1. 定义3个类,全部代码.效果:能默写,关键词全部正确. 2. ⾯面向对象和⾯面向过程有什么区别? 答:面向对象以事物(对象)为核⼼,完成事件只是一个任务.面向过程以事件为核心,为了完成任务, ...
- Linux iptables重启后失效
解决办法如下: 输入完iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080 后 执行iptables-s ...
- Redirect HTTP to HTTPS on Tomcat
I have bought my SSL secure certificate and successfully installed on Tomcat with the keytool but ho ...