积木式思想其实是很自然的一个过程,从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--二进制层面的复用的更多相关文章

  1. C++设计模式 之 “组件协作”模式:Template Method、Strategy、Observer

    “组件协作”模式: #现代软件专业分工之后的第一个结果是“框架与应用程序的划分”,“组件协作”模式通过晚期绑定,来实现框架与应用程序之间的松耦合,是二者之间协作时常用的模式. #典型模式: Templ ...

  2. 在C++中调用DLL中的函数 (3)

    1.dll的优点 代码复用是提高软件开发效率的重要途径.一般而言,只要某部分代码具有通用性,就可将它构造成相对独立的功能模块并在之后的项目中重复使用.比较常见的例子是各种应用程序框架,ATL.MFC等 ...

  3. com和dll(一)

    1.com为一种规范,使不同语言能在二进制层面上进行交互. 2.dll为ms的一种程序打包文件,使程序的代码能分开打包编译,并能在运行时共享.

  4. DLL模块:C++在VS下创建、调用dll

    1.dll的优点 代码复用是提高软件开发效率的重要途径.一般而言,只要某部分代码具有通用性,就可将它构造成相对独立的功能模块并在之后的项目中重复使用.比较常见的例子是各种应用程序框架,ATL.MFC等 ...

  5. .NET Core跨平台的奥秘[中篇]:复用之殇

    在<.NET Core跨平台的奥秘[上篇]:历史的枷锁>中我们谈到:由于.NET是建立在CLI这一标准的规范之上,所以它天生就具有了"跨平台"的基因.在微软发布了第一个 ...

  6. 在C++中调用DLL中的函数(3)

    1.dll的优点 代码复用是提高软件开发效率的重要途径.一般而言,只要某部分代码具有通用性,就可将它构造成相对独立的功能模块并在之后的项目中重复使用.比较常见的例子是各种应用程序框架,ATL.MFC等 ...

  7. C++在VS下创建、调用dll

    转自:http://www.cnblogs.com/houkai/archive/2013/06/05/3119513.html 目录 1.dll的优点 代码复用是提高软件开发效率的重要途径.一般而言 ...

  8. DLL导出类避免地狱问题的完美解决方案

    DLL动态链接库是程序复用的重要方式,DLL可以导出函数,使函数被多个程序复用,DLL中的函数实现可以被修改而无需重新编译和连接使用该DLL的应用程序.作为一名面向对象的程序员,希望DLL可以导出类, ...

  9. Objective-C 里面的类对象复用小结

    OC 提供了单继承 (Inheritance), Category, Extension, Protocol 这几种基本的类与对象层面的复用机制,作一小结. 在这几个机制中,继承提供了纵向的复用,可以 ...

随机推荐

  1. C++学习之类的构造函数、析构函数

    在C++的类中,都会有一个或多个构造函数.一个析构函数.一个赋值运算操作符.即使我们自己定义的类中,没有显示定义它们,编译器也会声明一个默认构造函数.一个析构函数和一个赋值运算操作符.例如: //声明 ...

  2. ant新建scp和sshexec任务

    1.build.xml中新建targer如下: <target name="remotecopytest" description="拷贝文件到远程服务器" ...

  3. 2013 imac 安装 win7

    昨天晚上安装imac win7系统,其实步骤是很简单的,首先需要一个用boot camp助手做好的win7安装U盘或者有个外接光驱加一张win7光盘,然后用boot camp助理划分一个分区给win7 ...

  4. BZOJ 1271 秦腾与教学评估

    二分. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> ...

  5. Palindrome_滚动数组&&DP

    Description A palindrome is a symmetrical string, that is, a string read identically from left to ri ...

  6. 破解 crackme4(深入底层抓出关键算法)

    系统 : Windows xp 程序 : crackme4 程序下载地址 :http://pan.baidu.com/s/1nu452xN 要求 : 注册机编写 使用工具 : OD & IDA ...

  7. 内存回收,Dispose,Close,Finalie(C#中的析构函数)

    NET中的资源分托管和非托管,所谓的托管是指CLR(通用语言运行时)中进行管理的资源,它可以由CLR自动进行内存回收. 也就是大家熟知的GC(垃圾回收机制). 而对于 非托管资源,比如数据库连接,CO ...

  8. 进程process和线程thread的关系

    写的很好很明白cpu每次只能执行一个进程,所以其他进程会挂起 在一个进程中,允许存在n个线程,n个线程共享这个进程中的资源 多个线程在共享的时候存在资源互斥,一次只能一个线程,会需要加锁 一次存在固定 ...

  9. OpenFlow Switch学习笔记(四)——Matching

    这次我们着重详述来自于网络中的数据包在OpenFlow Switch中与Flow Entries的具体匹配过程,以及当出现Table Miss时的处理方式,下面就将从这两方面说起. 1.Matchin ...

  10. CSS2伪类选择器要点

    有四个选择器,分别是 hover:鼠标悬停 link:链接不能使用时 visited:链接被点击后 active:链接被点击时,如果鼠标不放,就会一直触发active属性 link在w3c中记录为链接 ...