1、概述
计算机代码能够在
计算机系统或设备内的
中央处理器(CPU)或 其它计算处理器上执行。常见的CPU架构包括但不限于,INTEL x86系列、ARMRISC(精简指令集代码)架构、SUNSPARC和 MOTOROLA68000。代码可以写成人类能够理解的高级程序语 言,比如C、C++或JAVA,但最终这些代码会被计算环境编译和汇 编成在示例计算机处理器上执行的机器指令。
CPU可以处于软件环境中,该软件环境通常被称作系统平台。 该平台可以包括操作系统,比如为更大型计算环境设计(例如,桌面 系统、膝上个人计算机)的MICROSOFTWINDOWS和Linux。 对于更小型的计算环境(例如,移动和通信设备),有多种操作系统 正在使用,包括但不限于,Linux、SymbianOS、WindowsCE、 PalmOS、BREW、REX和Itron。
平台通常可以为特定目扩展操作系统而维护额外的功能。例 如,WinCE.NET、Smartphone和PocketPC平台使用的是Windows CE 操作系统,但在其它方面有所不同,比如
用户界面——即, WinCE.NET能以工业设备为目标,PocketPC能以带
触摸屏的个人数 字助理(PDA)为目标,Smartphone能以
键盘操作的移动蜂窝电话为 目标。平台还能包含根据特定计算应用定制的扩展功能。在提供的 例子中,PocketPC平台可以在PDA上维护一系列个人信息管理功 能,而Smartphone平台可以装配适合
移动电话的通信功能。
在传统系统中,创建能够在特定平台上运行的二进制代码可以 通过使用工具链编译构建代码,比如为特定平台(和/或操作系统) 提供的软件开发套件(SDK)。在给定的操作系统上需要不同的SDK 来开发不同平台的代码(例如,Symbian Quartz需要的SDK与 Symbian Crystal不同)。如果为特定平台开发代码使用了不合适的 SDK,生成的二进制代码就无法运行在期望的平台上。
在源代码级,有些操作系统对代码的编写方式施加了限制和规 则。例如,SymbianOS要求创建的代码不能使用可写静态变量或全 局变量。作为这些限制的结果,一开始为一个操作系统编写的先前 的代码可能无法在另一个要求不同代码规则的操作系统上编译。虽 然如此,普遍的做法是编写单一的可以随后在多平台构建的源代 码。在实现时,可以开发通用源文件。通用源文件可以通过选定平 台的工具链分别处理,从而从单一源文件创建多个不同的特定平台 的二进制输出。
2、动态链接和加载
计算机程序可以包含多个组件。当程序运行时,组件可以组合 在一起形成完整的功能系统,并可以被加载进协作计算环境的主存 储器中执行程序。合并计算程序组件的过程被称为链接。当程序组 件被合并进可以被加载进存储器执行的单个文件时,该过程被称为 “静态链接”。通常,链接程序是工具链的一部分,它以组件对象文件 作为链接程序的输入,连接这些文件形成单个输出文件。当程序是 由多个子程序组成时,一个子程序到另一子程序的引用可以通过符 号(比如变量和函数名字)做到。除了其它函数和操作,链接程序可 以在协作计算环境存储器通过符号(或多个符号)的
位置分解引用, 然后补上对子程序调用的对象代码,这样调用指令就能指向所需的 存储器位置。
在“静态链接”中,当程序调用存储在另一组件内的函数时,所 需函数代码能够由静态链接程序合并进可执行程序。实际做法是静 态链接程序将所有需要的函数代码拷贝进输出可执行文件。相反 的,“动态链接”可以使函数和组件只在执行程序的时候可用。因为 动态链接组件通常不与程序主要部分绑在一起,它们可以被多个可 执行程序共享。主程序还可以比静态链接的对应程序小很多,因为 实际代码不会成为程序的可执行文件的一部分,因为动态链接组件 作为分开文件存在。“动态链接”在当今的计算环境中十分普遍。例 如,在微软的WINDOWS中,动态链接组件被称为DLL(动态链 接库),在Unix/Linux中他们被称为共享对象(.so)文件。
举个例子,一个程序调用动态链接库中的函数,编译程序和链 接程序可以生成重定位表,其中包含在运行期能够允许协作计算环 境加载库和找到所需函数代码的信息。在动态链接库中,直到使用 该库的程序开始运行(被称为“加载期动态链接”)或直到程序开始第 一次调用(被称为“
运行期动态链接”),符号才与实际地址绑定。
动态可执行文件能够在动态链接程序/加载程序的控制下执行。 这些应用依赖动态库(或共享对象),其可由动态链接程序定位和绑 定以创建可运行进程。共享对象还能依赖其它共享对象,这些共享 对象也由动态链接程序管理。使用传统方法,处理用于动态链接和 加载的绑定、符号解析、代码重定位以使得可执行文件与共享对象 组合在一起以完整的程序运行的例程通常是计算环境的操作系统中 的一部分。
在实践中,动态库可以在加载期链接。当动态库被创建时,会 生成小的桩文件或导入库,它为计算环境提供可以用来加载动态库 和定位导出函数的信息(比如符号和重定位表)。导入库(或桩文件) 能够在主可执行程序生成时被链接,这样所有共享对象库中的函数 位置都为可执行程序中已知,即使实际共享对象的二进制代码依然 是分开的文件。当该程序被加载至存储器中开始执行时,动态库也 被加载,在桩文件提供的链接信息使得被导出的库函数可以被主程 序调用。
在运行时动链接时,发出调用的程序使用特殊函数在运行时加 载该库。例如,在Windows操作系统中,该函数是LoadLibrary;在 Linux中等价的函数叫做dlopen。使用这种方法,对动态库的加载不 是在发出调用的程序加载时自动发生的,而是推迟直到程序在运行 时调用这个特别的函数进行加载。该函数包括被加载库对象的路径 名,如果成功加载则返回该库的句柄。调用程序然后传递该句柄至 第二个函数(在Windows中是GetProcAddress,在Linux中是dlsym) 以获取被动态库导出的命名符号的地址。一旦该符号的地址(通常是 要调用的函数)被获取,该符号可以被调用函数调用。这个方法就不 需要导入库或桩文件。
2(a)、计算环境举例
图1描述的是一个根据在此描述的系统和方法的计算机系统100
实施例。计算机系统100能够执行各种的计算程序180。示例性计算 系统100主要由计算机可读指令控制,可读计算机指令可以是软件 形式,也可以提供指令指明该软件存储在哪,如何访问。该软件可 以在中央处理单元(CPU)110中执行,使
数据处理系统100工作。 在许多已知计算机
服务器、工作站和个人计算机中,中央处理单元 110由称为
微处理器的微
电子芯片CPU实现。
协处理器115是可选处 理器,与主CPU 110不同,它执行额外功能或辅助CPU 110。CPU 110可以通过互连器112与协处理器115相连。一个常见的协处理器 是浮点协处理器,也叫作数字或算术协处理器,它设计成比通用 CPU 110更快、更好的执行数字计算。
应该理解,虽然示出的示例计算环境包含单个CPU 110,这种描 述只是作为解释性目的,计算环境100可以包含多个CPU 110。另 外,计算环境100可以通过通信网络160或一些其它数据通信方式 (未示出)利用远程CPU资源(未示出)。
操作时,CPU 110取得、解码以及执行指令,通过计算机主数 据传输通路
系统总线105与其它资源进行信息传输。该系统总线连 接计算机系统100内的组件,是数据交换的媒介。系统总线105通常 包括发送数据的数据线,发送地址的地址线,以及发送中断和操作 系统总线的控制线。这种系统总线的一个例子是PCI(周边部件互 连)总线。一些当前高级总线提供称为总线仲裁的功能,用来控制扩 展卡、
控制器和CPU 110对总线的访问。挂接在这些总线上仲裁接 管总线的设备被称为总线主控。总线主控支持还允许通过增加总线 主控适配器创建总线的多处理器配置,这些适配器包含处理器和支 持芯片。
与系统总线105连接的存储器设备包括
随机存取存储器(RAM) 125和
只读存储器(ROM)130。这些存储器包括允许存储和读出信 息的
电路。ROM 130通常包含存储的不能
修改的数据。存储在RAM 125的数据可以被CPU 110或其它硬件设备读取或修改。对RAM 125和/或ROM 130的访问可以由存储器控制器120控制。存储器控 制器120可以提供地址转换功能,在指令执行时将虚拟地址转换成 物理地址。存储器控制器120还可以提供存储器保护功能,将系统 内的进程和系统进程与用户进程隔离开。这样,在用户模式运行的 程序通常只能访问它自己进程虚拟地址空间映射的存储器。换种说 法就是,程序无法访问另一进程的虚拟地址空间,除非进程间设立 了存储器共享。
此外,计算机系统100可以包含外置设备控制器135,其负责从 CPU 110到外置设备的通信指令,比如
打印机140、键盘145、
鼠标 150和数据存储
驱动器155。
显示器165由显示控制器163控制,用于显示由计算机系统100 生成的可视输出。该可视输出可以包括文本、图像、动画和视频。 显示器165可以由基于CRT的视频显示器、基于LCD的平板显示器、 基于等离子气体显示器、触摸屏或其它各种大小的显示器实现。显示 控制器163包括用于生成发往显示器165的视频
信号的电子组件。
此外,计算机系统100可以包含
网络适配器170,用于将计算机 系统100与外部通信网络160连接。通信网络160可以为计算机用户 提供电子形式的传输和发送软件和信息的方式。此外,通信网络160 可以提供分布式处理,它涉及多台计算机和工作负载的共享或执行 任务的协作努
力。要理解的是所示的网络连接只是以解释性为目 的,计算机间可以使用其它方式建立通信连接。
要理解计算机系统100只是为了解释这里描述的系统和方法可 以操作的计算环境,其不限制在此描述的系统和方法在拥有不同的 组件和配置的计算环境中的实现,因为在此描述的创造性概念可以 在具有不同的组件和配置的不同的计算环境中实现。
2(b)、
计算机网络环境示例
上述的计算系统100可以作为计算机网络的一部分部署。通 常,上述的计算环境可以同时适用于网络环境中部署的服务器计算 机和客户计算机。图2展示了示例网络计算环境200,其中,服务器 205通过通信网络与客户计算机通信,其中可以部署在此描述的设备 和方法。如图2所示,服务器205可以通过通信网络160(可以是固 定连线或无线LAN、WAN、内部网、外部网、点对点网络、因特网 或其它通信网络中的任何一个或它们的组合)与多个客户计算环境相 连,比如台式个人电脑210、移动电话215、电话220、个人电脑100 和
个人数字助理225。此外,在此描述的设备和方法可以通过通信网 络160与
汽车计算环境(未示出)、消费电子计算环境(未示出)和 建筑自动控制计算环境(未示出)协作。例如,在通信网络160是因 特网的网络环境中,服务器205可以是专用计算环境,其用于使用 任何一种公知的协议,比如超文本传输协议(HTTP)、文件传输协议 (FTP)、简单对象访问协议(SOAP)或无线应用协议(WAP)处理 和传送与客户计算环境100、210、215、220和225之间的数据。每 个客户计算环境100、210、215、220和225可以提供有一个或多个 计算程序180,比如网页浏览器(未示出)或移动桌面环境(未示出) 以访问服务器计算环境205。
操作时,用户(未示出)可以和在客户计算环境中运行的计算程 序交互,获得期望的数据和/或计算程序。数据和/或计算应用可以存 储在服务器计算环境205中,通过示例的通信网络160通过客户计算 环境100、210、215、220和225传送到协同操作用户。参与的用户 可以
请求访问全部或部分在服务器计算环境205上的特定数据和应 用。该数据通信可以在客户计算环境100、210、215、220和225与 服务器计算环境之间传送,进行处理和存储。服务器计算环境205 可以装有计算程序、进程和小型程序(applet)用以生成、验证、加密 和传送数据,可以与其它服务器计算环境(未示出)、第三方服务供 应商(未示出)、网络存储(NAS)和存储区域网络(SAN)以实现 这样的数据事务。
因此,在此描述的设备和方法可以在具有客户计算环境与服务 器计算环境的计算机网络环境中使用,其中客户计算环境访问网 络,与网络交互,服务器计算环境与客户计算环境交互。但是,这 些提供移动性设备平台的设备和方法可以使用各种基于网络的架构 实现,不应局限于展示的例子。
3、平台依赖链接
可执行程序通常是依赖平台的。换种说法就是,一个特定程序 在开发时目标就是要在特定平台上运行,因此它必须为特定平台编 译、链接和构建。同时,该过程生成的二进制可执行文件通常无法 在不同的平台上运行。在传统系统中,需要为每个不同的操作系统 分别构建动态库。当要支持多个操作系统时,要使用专用工具将库 代码构建成多个共享对象(动态库),即每个操作系统一个。如果代 码没有明确参考单个平台的唯一项,则为给定的操作系统创建共享 的对象库,并使该库在从该操作系统导出的多个平台上运行就足够 了。相反的,如果库代码对平台唯一函数有明确依赖关系,则要为 给定平台服务构建共享对象,而且该共享对象通常无法在缺少明确 依赖性的其它平台上运行。
在操作系统支持多个平台的例子中,这组程序组件通常会包 括,但不限于以下组件:与平台唯一依赖的可执行二进制文件;为 基于该平台的操作系统而构建的一组可选共享对象(动态库)。
图3展示了示例性计算环境300执行运行时“动态链接”时执行的 过程。如图3所示,在
块350中程序源文件355被编译以创建对象文 件。类似的,在块310库源文件305被编译以创建动态库。编译350 生成的对象文件在步骤345中被静态链接,以创建动态二进制执行 文件。
如图3所示,二进制可执行程序可以在步骤340中运行。运行 时,该程序可以在步骤335发出指令调用,以打开为该运行程序使 用的库。作为回应,在主环境提供的动态链接程序320加载所需库 315至该运行程序的地址空间,返回该库的句柄。该程序然后可以在 步骤325中将该库句柄传给特殊函数来获得由该库315导出的特定符 号的地址。这些提到的该特殊函数通常由操作系统提供;例如,在 微软Windows中,该特殊函数叫做GetProcAddress。获得地址后, 由库导出的该符号在步骤330就可以被运行的程序调用。
图4和图5描述如何用传统方法处理源处理代码使之在多个操作 系统和平台中运行。参看图4,其中单个操作系统A 485支持两个平 台A1 475和A2 480,图4展示的示例性动态链接架构400具有库源 文件405和程序源文件415。库源文件405在块410被编译以创建操 作系统A 485的动态库430。
类似的,程序源文件415在块420被编译以为平台A1 475创建 对象文件,在块425被编译以为平台A2 480创建对象文件。编译420 得到的对象文件静态链接以创建所到的动态可执行对象文件A1exec 435(例如,在平台A1 475上可执行)。同样,如图所示,编译425 得到的对象文件被静态链接,创建得到动态执行对象文件A2exec 440(在平台A2 480上可执行)。动态链接程序455在运行时将动态 库430与执行程序A1exec 435链接,响应该运行程序打开该库的调 用445。库430被加载进操作系统A 485的地址空间中,以创建链接 完成的在平台A1 475上运行的可执行文件465。类似的,动态链接 程序460在运行时将动态库430与执行程序A2exec 440链接,响应 该运行程序打开该库的调用450。库430被加载进操作系统A 485的 地址空间中,创建链接完成的在平台A2 480上运行的可执行文件 470。在操作中,完成链接的可执行文件465或470各自从动态库430 中调用函数或获取数据。
参看图5,图5展示的示例动态链接架构500具有库源文件505 和程序源文件515。库源文件505在块510中被编译以为操作系统B 585创建动态库(530)。
类似的,程序源文件515在块520被编译,为平台B1 575创建 对象文件,并在块525被编译,为平台B2 580创建对象文件。编译 520得到的对象文件被静态链接,以创建得到的动态可执行对象文件 B1exec 535(例如,在平台B1 575上可执行)。同时,如图所示, 编译525得到的对象文件被静态链接,以创建动态执行对象文件 B2exec 540(在平台B2 580上可执行)。动态链接程序555在运行 时将动态库530与可执行程序B1exec 535链接,响应运行程序打开 库的调用545。库530被加载进操作系统B 585的地址空间中,以创 建运行于平台B1 575上的链接完成的可执行文件565。类似的,动 态链接程序560在运行时将动态库530与可执行程序B2exec 540链 接,响应运行程序打开库的调用550。库530被加载进操作系统B 585的地址空间中,以创建运行于平台B2 580上的链接完成的可执 行文件570。在操作中,完成链接的可执行文件565或570各自从动 态库530中调用函数或获取数据。
如图4和图5所示,有一组分别包括应用程序415和515和库文 件405和505的共同源代码。在解释性实现中,编写的应用程序可以 运行在四个不同的平台上,即由共同的操作系统A 485而来的平台 A1 475和A2 480,由操作系统B 585而来的平台B1 575和B2 580。 应用415和515的源代码能够维护对应各个平台的指令,分别是平台 A1 475、平台A2 480、平台B1 575和平台B2 580,应用415和515 的源代码编写方式可以使得它们对平台的依赖性在编译时被识别出 来。
在提供的实现中,库405和505的源代码通常无需维护特定平台 依赖性。在说明性操作中,库可以被协作应用程序调用,可以作为 动态库操作。如图4所示,每个平台(475和480)能够要求它们自 己的动态可执行文件A1exec 435、A2exec 440,这些动态可执行文件 可以通过平台特有的编译程序工具(例如,编译程序块420和425) 编译共同的应用源文件415创建。在说明性实现中,协作动态库430 可以创建一次,然后动态链接到可执行文件Alexec 435或A2exec 440中,以在各个平台A1 475和A2 480中创建可运行进程。
图5示出了两个额外的可执行文件B1exec 535和B2exec 540被 编译以允许应用在平台B1 575和平台B2 580上运行。此外,创建新 的动态库530以与可执行文件B1exec 535和B2exec 540链接,因为 可执行文件B1exec 535和B2exec 540是为操作系统B 585构建的。 在此实现中,为了实现跨越运行于两个操作系统(分别是操作系统A 485和操作系统B 585)的四个平台(平台A1 475,平台A2 480,平 台B1 575,和平台B2 580)的动态链接,需要构建四个动态可执行 文件和两个动态库。要理解使用传统方法,开发能够运行于不同的 计算环境的二进制对象是要耗费大量资源的。
图6示出了示例计算环境600的组件。如图6所示,在源代码 607和CPU 670之间可以存在层次结构605、610和615。这种层次 结构在高层和底层存在高度共同性但在之间区别明显。在最高层 605,源代码607对于具有有限平台特有的元素620的所有协作平台 来说大部分都相同。在最低层615,代码运行在CPU 670上。在所示 的实现中,当CPU 670架构在一些不同计算环境(未示出)中都相 同时,低层机器指令也应该是相同的。但是
中间层610可以维护多 个操作系统640、655和665,每个系统有多个平台变体630、635、 645、650和660,由于不同的特性和工具链,它们需要各自不同的二 进制文件。同样如图所示,顶层605包含平台无关源代码625,可以 与平台和操作系统都无关。
在示例性实现中,参看图6,有五个平台操作在三个操作系统 上。具体而言,平台A1 630、平台A2 635运行在操作系统A 640上, 平台B1 645和B2 650运行在操作系统B 655上,平台C1 660运行 在操作系统C 665上。使用传统方法,需要创建每个应用程序的五 个不同版本(每个平台一个)加上三个单独的动态库(每个操作系统 一个),以保证计算机程序的正确操作。在此描述的系统和方法的目 标是通过提供能跨越五个平台和两个操作系统的单个动态库来改善 传统实践的缺点。在示例性实现中,可以创建单组二进制库,其在包 含特定CPU架构的所有系统上可用,而无论在该CPU上运行的操作 系统,这样就可以利用图6中顶层605和底层615的共同性。
在此描述的系统和方法可以应用到不同的计算环境中。在示例 性实现中,在此描述的系统和方法可用于桌面系统,它通常包含 INTELx86家族的处理器。桌面PC的通用操作系统是微软的 WINDOWS和Linux,两者都有动态链接功能。但是这些操作系统 为它们的二进制对象使用了不兼容的格式,因此需要为Linux和 WINDOWS提供不同的二进制文件,尽管它们运行在相同的CPU 上。
在移动和嵌入式设备上,多样性问题可能更显著。具体而言, 移动和嵌入式设备使用更多数量的操作系统,包括但不限于, Linux、WINDOWSCE、PalmOS、SymbianOS、BREW、Itron。 但在CPU级615,根据选定的计算机硬件架构可以有相当的共同 性,比如ARM RISC架构。当前的实践不利用此共同性,相反根据 操作系统或平台层(如610)定制创建库。
在说明性实现中,在此描述的系统和方法可以被应用到所选的 计算环境市场(例如,移动设备市场)来发行能够在拥有选定硬件架 构(例如,设备包含ARM处理器)的计算环境上运行的单个软件库, 而不管软件平台。这种方法能够提供为软件开发商和客户同时提供 各种商业好处,包括但不限于,节省开发和维护多个平台专用版本 库的成本。此外,通过同一组件在多个平台安装累积的经验,代码
质量可以更快的建立。另外,使用这种方法,对库的修改可以更彻 底有效的测试。设备制造商(例如蜂窝电话制造商)可能在他们不同 产品线上部署共同的库,如果该库在单个产品线已经被证实可用。
下面的说明性实现和图具体涉及运行时库的动态链接。
图7A展示示例性平台无关二进制对象和链接架构700。如图所 示,平台无关二进制对象和链接架构700包含源代码和平台无关源 代码组件,源代码包括主应用源代码705,平台无关源代码组件它包 括但不限于平台无关动态库(PIDL)源代码725;编译程序730、PIDL 对象文件735、PIDL动态加载程序/链接程序源代码720。
在说明性操作中,PIDL源代码725在块730被编译成标准对象 格式,该标准对象格式创建PIDL对象735。如图7所示,在步骤 770,主程序源代码705和动态加载程序/链接程序源代码720(例如, 编译组件源代码组745)为目标平台编译构建。得到的动态二进制执 行文件795使用主应用函数775和动态PIDL加载程序/链接程序函数 785,从PIDL对象文件735中调用函数和获取数据。
要理解,虽然示出示例性平台无关二进制对象和链接架构700具 有特定配置的不同的组件并执行特定操作,但这种描述只是为了说 明性目的,在此描述的发明概念可以应用到拥有不同组件、配置和 操作的任何平台无关二进制对象和链接架构。
在说明性实现中,示例性平台无关二进制对象和链接架构700 可以根据以下方法操作。PIDL对象文件735能够创建成定义好的标 准对象文件格式。动态加载程序/链接程序720可以作为主应用程序 705的一部分被编写。在提供的实现中,如果目标平台是已知的,合 并成的源代码(例如,这组编译组件源代码745)能够被编译成给定 平台(未示出)的二进制可执行代码795。在运行时,动态加载程序 /链接程序785(例如,编译的加载程序/链接程序)能够根据运行的 应用775的指令加载库735,向PIDL文件735返回的句柄。动态链 接程序/加载程序785还包含获得被该PIDL 735导出的符号的地址的 函数,允许应用775通过返回的符号地址
指针调用该PIDL符号为自 己所用。
如上所述,动态库的平台无关性可以首先通过将库源代码725 编译成已知对象文件格式735实现。在该精心设计的实现中,PIDL 源代码725不含有对任何特定平台的依赖性。对象文件格式(未示 出)通常可以包含多种类型的信息,包括但不限于,头部信息比如代 码大小、编译器或汇编器生成的对象代码,链接程序785要用到的重 定位信息-当对象代码的地址被链接程序改动时,要从此模块导入 或从其它模块导出的符号的符号表。
在说明性实现中,平台无关二进制对象和链接架构700可以用 不同的对象文件格式,包括但不限于,ELF(可执行和链接格式)、 微软可移植可执行(PE)格式和其它对象格式(例如,专
门为在此 描述的系统和方法设计的对象格式)。
传统上,不同的操作系统和平台使用不同的对象文件格式。这 些平台的链接程序和加载程序期望接收这些预定格式的可链接对 象,且拒绝其它格式。当该平台也提供动态链接时,动态链接程序 就是操作系统的一部分,可以“固定连接”到唯一的对象格式。
在此描述的系统和方法通过提供通用加载程序/链接程序720改 善这个缺点。在说明性实现中,通用加载程序/链接程序720可以编 写成以选定的对象文件格式(例如,ELF或选择的任何其它对象格 式)处理对象文件。在操作中,通用加载程序/链接程序785操作以 定位PIDL对象文件735内的符号、重定位信息以及其它信息。如图 7所示,加载程序/链接程序720的部署可以通过创建与协作主应用 705源代码一起编译的源代码完成。这种情况下,链接和加载控制就 从操作系统中去除,被包含在运行可执行文件中。动态加载程序/链 接程序785同样可以操作处理非PIDL库。这种情况下,动态加载程 序/链接程序785可以设计成确定动态库是PIDL类型还是非PIDL类 型,并相应地处理该PIDL或非PIDL库。在说明性实现中,当处理 的是非PIDL库时,链接和加载控制可以传递给底层的操作系统。
在说明性实现中,PIDL对象文件可以跨越不同平台部署而无需 重新建立或编译。在此实现中,因为主应用程序与选定平台的动态 链接程序/加载程序一起编译,且因为链接控制是不依赖平台的,而 是放在可执行文件内部,这样就可以完成在不同平台上的运行时链 接PIDL而无需重编译或生成PIDL对象。
动态链接程序/加载程序785包含可以被应用程序775使用的函 数调用(PIDLOpen,PIDLClose,GetPIDAddress),以打开和封闭 PIDL对象735,返回由该PIDL导出的符号地址。打开和封闭该 PIDL涉及在运行的应用的存储空间中加载和卸载该PIDL对象,执 行任何需要的符号地址的重定位。GetPIDLAddress函数返回PIDL符 号的重定位地址,以允许该应用775通过指向这个地址的指针来调 用该符号。GetPIDLAddress查询该PIDL对象文件中的符号表来寻找 该符号地址,假定该库的
基础存储地址为零。在重定位后该地址被 返回,以允许该PIDL被加载进存储时实际的、非零基础的地址。在 动态链接程序/加载程序785中函数的联合使用允许在运行期动态链 接,去除在加载期动态链接需要的库的桩文件。
要理解在此描述的系统和方法允许主应用在运行时访问部署成 PIDL对象的动态库,只要主应用是使用动态链接程序编译的。图 7A的实现提供了导出的PIDL符号供主应用775使用。该PIDL也可 以导入主应用775包含的符号,以创建双向依赖关系。在此描述的 系统和方法同样适用于当PIDL需要访问主应用中的功能(如图8所 示)。如图8所示,函数或符号A和B的代码可以位于主程序810 中,函数C、D可以位于动态库820中。在说明性实现中,为了使动 态库820调用A和B,或者主程序810使用库函数C或D,所有函 数的符号和位置都必需在合并的程序中分解。在说明性实现中,该 操作可以通过示例性链接程序(未示出)执行。
使用传统的方法,该动态链接程序通常是操作系统的一部分。 在此背景下,因为不同系统使用他们各自的链接程序和对象格式, 结果是依赖平台的库格式。在给定平台中,库820可以调用回主程 序820中(例如,访问函数A和B),因为主程序810的对象文件格 式已知。该库可以使用在该动态链接程序提供的运行时函数调用(例 如在Windows中的GetProcAddress)来寻找从主程序810导入的符 号地址,然后调用导入的符号为该库自己所用。这些函数在相反方 向的调用都是相同的,由程序810定位由库820导出的符号,因为在 单个平台中,所有的对象文件使用的都是相同的已知格式。
但是这种传统的方法在此处公开的平台无关例子中就无法起作 用。运行时链接函数(PIDLOpen,PIDLClose,GetPIDLAddress)在 处理由该PIDL导出符号时能单方向正确操作,因为该PIDL被创建 成定义好的对象格式(例如ELF),该格式对于动态链接程序/加载 程序785是已知的。GetPIDLAddress在搜索它的符号表以返回符号 地址时期望的是该预定义的对象格式。但该函数调用无法处理导入 至该PIDL的符号,因为动态二进制可执行文件795是为特定目标平 台创建的,因此它的对象格式是平台相关的,很可能与在链接程序 785中提供的GetPIDLAddress函数期望的格式不同。尽管图7A中的 演示实现足够处理导出的符号,还需要进一步的改进才能处理图8 中描述的情况,其中符号也被导入至该库中。
图7B展示了平台无关二进制对象和链接架构示例700,它被扩 展使得可以处理导入符号。如图所示,平台无关二进制对象和链接 架构700包含源代码,其中包括主应用源代码705和平台无关源代码 组件,它包括但不限于平台无关动态库(PIDL)源代码725;编译程 序730,PIDL对象文件735,PIDL动态加载程序/链接程序源代码 720,定义的应用程序接口(API)710和API解析程序715。
在说明性的操作中,PIDL源代码725在块730中被编译成标准 对象格式,创建PIDL对象文件735。类似的,应用程序接口(API) 解析程序715可以操作API 710生成PIDL_getSymbol函数,允许协 作主应用705被该PIDL对象文件735访问。如图7B所示,主应用 源代码705、动态加载程序/链接程序720的源代码,如果被执行的话 还有PIDL_getSymbol函数源代码755(例如,编译组件源代码745) 在步骤770为目标平台编译创建。得到的动态二进制可执行文件795 使用主应用函数775、PIDL_getSymbol函数780和动态PIDL加载程 序/链接程序函数785从PIDL对象文件735中调用函数和获取数据。
在此背景下,主应用暴露给PIDL库的功能API(图7B的710) (应用编程接口)可以首先被
指定和公布(这样该PIDL就可以使用 被暴露的函数)。该API(图7的710)然后可以被解析以生成源代 码函数PIDL_getSymbol(图7B的755),它可以作为主应用的一部 分被编译(如图7B所示)。此外,源代码755没有平台依赖性。在 运行时,PIDL库735可以通过要导入的符号名字作为参数调用 PIDL_getSymbol函数,从而导入定义在应用接口API710中的符号。 PIDL_getSymbol函数返回请求的符号的地址,然后PIDL库可以通过 返回的地址调用该符号。
通过编译PIDL_getSymbol源代码,该PIDL库可以确保访问到 导入的符号地址,即使该源代码745是为不同的平台而编译的。该 源代码能够找到和返回所请求的符号的实际地址,而不管编译过程 770生成的对象格式是什么。在操作中,主程序可以调用存在于动态 库内的命名函数(使用GetPIDLAddress),动态库也可以调用主程序 中的函数(通过调用PIDL_getSymbol)。为了使合并的程序正确工 作,一旦加载程序将所有的对象代码组件加载至计算环境的存储器 中,函数调用可以被分解和重定位从而得到正确的地址。
生成源代码函数PIDL_getSymbol的另一实施例展示在图7C 中。如图所示,平台无关二进制对象和链接架构700包含源代码, 其中包括主应用源代码705和平台无关组件源代码,它包括但不限 于平台无关动态库(PIDL)源代码725;编译程序730,PIDL对象 文件735,PIDL动态加载程序/链接程序720的源代码,对象解析程 序740。
在演示的操作中,PIDL源代码725在块730中被编译成标准对 象格式,创建PIDL对象文件735。类似的,对象解析程序740可以 操作该对象文件735生成PIDL_getSymbol函数,允许协作主应用 705被该PIDL对象文件735访问。如图7C所示,主应用源代码705、 动态加载程序/链接程序720源代码,如果被执行的话,还有 PIDL_getSymbol函数源代码755(例如编译组件源代码745)在步骤 770为目标平台编译创建。得到的动态二进制可执行文件795使用主 应用函数775、PIDL_getSymbol函数780和动态PIDL加载程序/链接 程序函数785,从PIDL对象文件735中调用函数和获取数据。
对象文件格式(未示出)通常可以包含多种信息类型,包括但不 限于,头部信息,比如该代码的大小、被编译程序或汇编程序生成的 对象代码、当对象代码的地址被链接程序改动时,链接程序785要用 到的重定位信息,要从此模块或从其它模块导出的符号的符号表。
知道期望对象格式的解析程序740可以解析对象,识别被该对 象导入的符号,根据解析的结果生成函数源代码755以获得各导入 符号的地址。对象解析程序740解析PIDL对象文件735,提取符号 名字和属性,创建源代码文件755(例如,以高级语言,包括但不限 于,“C”语言或等价的语言)作为解析程序的输出。该 PIDL_getSymbol源代码755执行与图7B中相同名字的源代码一样的 功能。实现方法的不同之处在于,在图7B中,解析API 710会将主 应用API中的所有符号暴露出来,不管它们是否被PIDL 735用到。 在图7C中,解析对象文件735的结果是只暴露那些实现需要导入到 库735的符号。
在说明性实现的说明性操作中,当主程序开始运行,它可以被 平台加载程序加载至存储中。在执行期间,主程序决定它是否发出 调用来加载外部的库。该调用会调用PIDL加载程序/链接程序,其 首先决定包含有被该调用函数的库名字和路径。如果该库是如微软 的DLL(即不是PIDL)的普通平台特有的动态库,如果平台有相 应的加载程序,链接程序将控制传递给普通平台库加载程序。如果 相反,该库对象是一个PIDL,它就被加载进运行程序的存储空间 中。
响应“OpenPIDL”函数调用,链接程序/加载程序可以创建编程结 构来代表该PIDL对象。它然后可以查询该对象来寻找该代码大小 (例如,定义在可以访问到的对象文件格式的域内),可以分配合适 大小的固定存储块,将该PIDL文件加载至分配的存储中。
然后,链接程序操作以重新定位存储器中的符号地址。该PIDL 内的内部符号被重定位。在操作中,二进制文件包含对象代码内的 符号地址,但通常操作前提是库代码的基准起始地址是零。但该 PIDL被加载至不同的地址,因为PIDL是被加载进存储器,所以该 地址可以被确定。链接程序的重定位工作涉及调整符号的地址以反 映存储器实际起始地址。
在内部PIDL符号重定位后,链接程序可以访问被该PIDL调用 的包含在主应用中的所有外部符号。对于这些符号,链接程序可以 调用PIDL_getSymbol函数,用外部符号的名字作参数。因为该函数 包含被该PIDL导入的所有符号的列表,它可以匹配名字,返回该名 字符号的实际地址。在打开该PIDL的过程中,PIDL用这种方法获 得的实际地址接着调用导入的符号。
在此阶段,PIDL维护它导入和导出的符号的正确地址。重定位 完成后,该PIDL导出的符号的重定位的地址可以返回给链接程序。 主程序可以访问这些重定位的符号,当GetPIDLAddress从PIDL外 部调用PIDL的符号时,该符号的正确地址被返回。
在此描述的系统和方法可以被链接至单个应用的多个库(例如多 个PIDL)使用。这些库在运行时可以互相调用,第一个库使用 OpenPIDL和GetPIDLAddress可以访问第二个库导出的函数和符 号。使用多个库时,从主应用导入符号的链接机制可以同构应用。 每个动态库被保存为标准的对象格式,PIDL_getSymbol桩以源代码 的形式被生成,它包含对由该PIDL导入的符号的引用。这可以如图 7B展示的方式创建,通过解析主应用暴露的API,或者如图7C所示 的通过解析每个库对象,将从每个解析操作得到的源代码
整理成单 个PIDL_getSymbol函数。该主程序与该PIDL使用的整理得到的 PIDL_getSymbol代码一起编译。在运行时,被调用的库被加载程序/ 链接程序加载和重定位,PIDL库和主程序之间返回符号指针的信息 被该动态加载程序/链接程序(例如图7A-C中的785)处理, PIDL_getSymbol代码(例如7B-C中的755)被编译进该程序。
4、平台无关动态库
图9展示了示例计算环境在一个或多个PIDL的运行期时链接时 的处理过程。如图所示,处理在块900开始,其中动态二进制可执 行文件被编译构建(如图7所示,动态二进制可执行文件可以包括但 不限于被编译的主应用源代码、PIDL加载程序/链接程序源代码和 PIDL_getSymbol函数源代码)。处理前进到块910,其中动态可执行 文件运行于计算环境中。处理然后前进到块915,其中确定协作计算 机程序调用了PIDLOpen函数以打开库。在块920,该加载程序搜索 PIDLOpen调用中指定的路径,然后在块925中执行一个检查决定搜 索是否成功。如果不成功,在块930PIDLOpen返回的参数Null,处 理结束。
但是,如果在块925中在指定的路径找到该PIDL对象,则处理 前进到块935,其中创建PIDL对象的程序结构,这样该PIDL对象 文件和它预定的文件格式就可以被查询。该PIDL对象的大小在块 940中被确定,处理然后前进到块945,其中存储块被分配,该PIDL 对象文件可以被加载进被分配的存储块中。在块950中,使用符号 表和从该对象文件提取的加载地址重新定位该PIDL的内部符号。在 块955中执行检查确定该PIDL是否也导入符号。如果否,则处理前 进至块965。但如果使用了导入符号,在块960中该动态链接程序调 用PIDL_getSymbol函数以分解该导入符号的实际地址。处理前进到 块965,提供识别该PIDL的句柄给发出调用的程序。PIDLOpen过程 在块970结束,加载该PIDL进存储器,解析该符号地址和返回句 柄。
在块975,发出调用的程序可以通过调用GetPIDLAddress函数 来访问一个导出的PIDL符号。该函数在动态链接程序/加载程序中 提供(例如图7的785),在块980中获取由该PIDL导出的符号地 址,将它返回给发出调用的程序。从那开始,在块985中,发出调 用的程序可以使用通过块980返回的指向该地址的指针来调用该 PIDL符号给自己使用。
5、在受限环境中的动态链接机制
一些操作系统不提供动态链接能力。当在这些系统上使用库 时,库被静态链接——即,库在链接时绑定到二进制可执行文件 中。可执行文件也可以是静态的,因为其可用于执行而无需额外的 链接,而且,在链接完成后不可以改变。通常,静态链接库无法做到 不冲击(例如,中断或停止)它绑定的底层程序而改变。同时,因为 库中的例程和数据的地址被绑定到程序中,对这些地址的改变会使 得绑定的程序出错。
在此描述的系统和方法通过在不提供本地动态执行支持的操作 系统上在运行时提供动态执行从而改善此缺点。在说明性实现中, 动态链接可以被认为是推迟链接直至运行期或加载期的能力,或者 可执行程序使用未与其静态链接的库的能力。此外,在此描述的系 统和方法允许特定操作系统本身不支持的二进制对象格式的链接。
在说明性实现中,大程序可以被分成主应用加上提供支持功能 的一组库组件。使用传统方法,该程序整体上会作为单个静态可执 行文件提供。这样,如果程序需要做出改动,需要构建整个新的可 执行文件,发行以替换未改动的版本。相反的,在说明性实现中, 可以与使用组件的应用无关而一次性提供组件。这样,应用可以拥 有更小的大小,如果需要新的或改动应用,只是应用本身需要重新 创建,而无需重建相关的库。
相反的,在提供的实现中,如果应用保持不变,但一个组件需 要改动,新的组件可以替换早期的版本而无需改动其它组件。只要 修改版本的符号名字一样,新版本的组件可以在运行期链接到原始 的应用程序和其它组件中。在说明性实现中,动态链接程序负责地 址重定位。如果新版本组件中的符号位于不同的地址,该地址在运 行期依然可以被分解和重定位。
图10示出了当在不支持动态执行的计算环境中部署PIDL时执 行的处理。如图10所示,处理开始于块1000,其中程序被分成主应 用和一个或多个库,目的是作为动态库在运行期部署。在块1020, 库然后可以被编译进PIDL对象文件,它拥有已知的标准文件格式。 在块1010,主应用的源代码和动态链接程序/加载程序源代码以及可 选地,在PIDL从应用中导入符号的情况下,还有PIDL_getSymbol 函数的源代码一起编译。该链接程序/加载程序组件拥有前面描述过 的功能,解释已知标准文件格式的PIDL对象文件,将它加载进存 储,执行必要的链接操作以分解和重定位库和协作应用之间的符 号。
上述在块1000-1020执行的所有功能和/或操作都可以在
构建时 执行,即在程序部署和执行之前。在不提供动态链接本地支持的受 限环境中,接着的构建的可执行文件和外部库之间的协作或交互通 常无法实现。相反,说明性实现提供了额外块1040至1090以来提供 加载期和运行期的动态操作。在块1040,构建的可执行文件开始执 行,在块1050,可以在本地操作系统的控制下正常加载至存储。
运行程序可以在块1060调用PIDLOpen来打开PIDL库对象。在 块1080该PIDL文件提供给主机环境。处理前进至块1070,其中在 前面的块1010中与程序一起编译的链接程序/加载程序加载该 PIDL,执行符号解析以绑定运行应用存储空间中的该PIDL对象。 该PIDL导出的符号在块1090被主程序通过动态链接程序/加载程序 提供的getPIDLAddress函数调用,如上面所述。
要理解,虽然所示的在受限环境中的动态链接操作方式中,库是 平台无关的,这种描述只是为了说明性目的,在此描述的发明概念 可以应用到与平台依赖的库中。
6、代码组件机制
在移动电脑(例如,比如PalmOS,SymbianOS)中使用的特定 操作系统(OS)强行限制对全局变量和静态可写变量的使用。这种 限制的存在使得操作系统可以避免对代码重定位的完全处理和对全 局变量的地址管理。因为静态变量放在与全局变量相同的存储器段 中,操作系统还可能禁可写静态变量的使用。当计算机程序代码为 此种操作系统编写时,当然可以遵守这种限制编写兼容代码。但是 当代码
片段,比如库代码要为不具该限制的不同平台编写时,代码 可能可能包含违反这些规则的地方而依然可以在受限操作系统上编 译或构建。这样就限制了在一些操作系统上使用第三方库和预先编 写的代码的能力,因此减少了它们的灵活性。这样使得开发效率更 低,因为时间要花费修改已有代码使之遵守操作系统的限制,或者 在某些情况下需要完全重写。
在此描述的系统和方法允许规避操作系统限制。在说明性实现 中,违反操作系统限制的库的源代码可以编译构建成PIDL格式。然 后该PIDL库与应用程序合并,然后运行在受限操作系统上。在此描 述的系统和方法的独特的动态加载和链接机制为该PIDL分配存储器 块。此外,在该实现中,全局变量在PIDL存储器区域之外不会被认 为是全局的。
这样,这样在该实现中,库内部定义的全局变量被限定在该存储 器区域之内,操作系统不可见,也就不会认为是全局变量。静态变 量也同样被限定在分配的存储器块内,不受操作系统干扰。结果就 避免了操作系统无法重定位该全局和静态变量。在该实现中,PIDL 加载程序/链接程序可以执行对库变量的重定位工作以完成它们的功 能。
图11展示的是受限计算环境处理PIDL的过程,该PIDL能够规 避该计算环境的一个或多个限制。如图11所示,处理开始于块 1100,其中PIDL由库创建,该库的代码违反了所述操作系统的一个 或多个限制。在块1110,与该库协作的计算应用被编译,与动态链 接程序/加载程序,如果该PIDL从该程序中导入符号,可选的还有 PIDL_getSymbol函数源代码构建在一起。
在演示的实现中,执行应用程序的指令在块1120被接收。在块 1130,可执行文件可以被主计算环境按通常方式加载。在块1140运 行的程序调用PIDLOpen打开PIDL库对象。在块1180该PIDL可以 提供给计算环境使用。作为对PIDLOpen调用的响应,动态链接程序 /加载程序(在块1110创建在程序中)可以在块1150分配存储块并 加载该PIDL进分配的存储块。如块1176所示,库中定义的全局和 可写静态变量的范围被限定在所分配的存储块中,无法在该存储块 之外通过名字访问。它们对所有的库函数有效因为这些函数也在分 配的存储块内,因此在该计算环境内库可以正确操作,尽管它违反 了在该环境的传统操作下的限制。由该PIDL导出的符号在块1170 可以被主应用通过如前面所述的动态链接程序/加载程序中提供的 getPIDLAddress函数调用。
要理解虽然展示的代码组件特性操作的方式中库是平台无关 的,但这种描述只是以演示为目的,在此描述的发明概念也适用于 与平台有依赖的库。
7、代码加载机制
在传统软件开发中,可以使用面向对象的方法。不是通过调用 函数来完成某个特定的任务,而是创建对象然后调用对象的方法来 执行希望的任务。这种方法是有益的,因为可以创建多个对象,而且 多个任务可以同时进行。有许多情况下执行计算任务的多个实例更有 利。例如,在播放和
渲染文档内的电影片段的库的例子。当某个此 类文档包含两个电影片段时,通过运行公共代码对象的两个实例来 同时播放它们将很方便。如果没有面向对象方法,开发人员将面临 这样一种情况,其中一个对象成功得执行一个任务,但很难允许多 个同样的对象同时执行任务。
虽然开发人员可以选择以面向对象的
风格编写代码,但这种选 择在集成第三方代码时就失效了。特别是对于库的代码开发,其中 库操纵数据并包含访问数据的函数。在说明性例子中,非面向对象 代码可以使用全局变量和只做一次初始化的静态变量。这种情况 下,在特定的计算环境中,这样就阻止了计算环境在同一进程内对 库对象的多次调用,因为单个进程可能只保存了一份用到的模块或 库的数据。具体的,同一对象的两次调用可能互相会扰乱它们共享 使用的有名全局变量。另一种情况,库可能编写成可以成功执行一 次,但即使该运行完成,企图运行第二次就会失败,因为静态初始 化的变量不再拥有必须的初始值了。这是因为静态变量是在创建时 由编译器初始化的,而不是在运行期,因此如果被初始化了的变量 在执行过程中被改变,接着的执行得到的改变过的值,与正确执行 需要的初始值不一样了。
在此描述的系统和方法目标是通过提供上述的PIDL加载机制改 善这些缺点。通过允许PIDL的多个实例使用限定在存储器块内的它 们自己“私有”的数据拷贝,在进程内只能使用单组数据的限制被去 除,这些就避免了传统方法中导致故障的相互作用和冲突。这种方 法允许相同进程内的多个实例和重复执行。它还使在不允许多个进 程的环境中执行多个并行进程成为可能。在说明性实现中,PIDL将 全局变量视为动态分配缓冲内的地址。单个PIDL可以被多次加载, 每个拷贝将拥有各自不同且无关的全局变量的拷贝,因此避免了存 在问题的交互。类似的,每次库要运行时,从文件加载一次拷贝, 因此它就含有正确初始化的静态变量。
图12展示了示例计算环境执行的处理过程,在说明性实现中, 当处理PIDL时可以使用它来避免受限代码组件间存在问题的交互。 处理从块1200开始,其中PIDL从库中创建,库的代码违反了禁止 重复执行的限制。在块1210,与库协作的计算应用与动态链接程序/ 加载程序和可选的PIDL_getSymbol函数源码一起编译并创建。
在演示的实现中,运行应用程序的指令在块1220被接收。在块 1230,执行文件可以被主计算环境按普通方式加载。在块1240,运 行的程序调用PIDLOpen打开PIDL库对象。在块1280,该PIDL可 以提供给计算环境使用。作为对PIDLOpen调用的响应,动态链接程 序/加载程序(在块1110被创建进程序中)可以在块1250加载该PIDL 对象,返回对象句柄给协作的应用。在块1260执行检查,确定是否 有新的PIDL实例要被加载进计算环境中。如果块1260的检查确定 新的PIDL实例要被加载,处理前进至块1270,其中该PIDL的新实 例被加载至不同的存储块中,与计算机程序链接在一起。如块1270 所示,该PIDL的每个不同实例由不同的句柄识别,允许每个实例单 独和无关访问。但是,如果在块1260确定不要加载新的PIDL实 例,处理回退至块1260的输入,从那继续。
要理解,虽然展示的代码加载特性操作的方式中库是平台无关 的,但这种描述只是以演示为目的,在此描述的发明概念也适用于 与平台有依赖的库。
8、封闭式或受限平台的扩展运行期(run time)环境
一些计算设备作为封闭式计算环境操作,这样该设备可能只能 执行该设备从制造商或供应商发货时自带的程序和应用。这类设备 (如移动无线设备)可以包含操作系统来运行自带的程序,但其它应 用无法无限制的加载进去,即使该应用是为其主机操作系统创建 的。这种封闭式平台的例子是称为特性电话的一大类移动手持设 备,除了语音功能之外,为这类设备提供了一组固定的特性(例如相 机功能),但这些特性是固定的,用户无法自行扩展。这类设备对于 发货后的应用是封闭的,因为它无法或限制向其中的计算平台增加 功能。
相反,开放式计算平台允许增加和运行为其操作系统编写的应 用。微软WINDOWS平台可以看作是个人电脑的开放式平台的例 子。在移动
手持设备领域,开放式平台的等价类被称为智能电话, 它提供无限制的增加在设备上运行的应用的环境。智能电话平台的 例子包括微软智能电话、Symbian的UIQ和Linux。
还存在第三类移动手持设备,它们是装配了运行期环境(RTE) 的特性电话。这种运行期环境的例子包括Java J2ME(Java2微版本) 和BREW(二进制无线运行期环境)。RTE允许手持设备以RTE应 用的形式增加功能——用J2ME时是Java小程序,用Brew环境时是 Brew认证的应用。这些应用有别于运行于如智能电话的开放式平台 上的应用,因为这些应用是为RTE而创建(例如,在一些情况下必 须为RTE认证以正确操作),不是为本地操作系统而创建。同样的, 这种支持RTE的特性电话相对智能电话有局限性,有些限制是基于 技术原因而有些是基于商业原因。
例如,硬件设备制造商、网络运行商或RTE提供商可以与应用 提供商签署排他或半排他协议,为他们特定的硬件设备提供应用和/ 或更新应用。通常,运行在RTE上的应用与设备的完整功能接口的 能力是受限的。例如,API(应用程序接口)允许控制网络堆栈,或 运行控制设备上的外围存储,从RTE可能不能访问该API。有时这 种情况被描述为RTE在本地计算环境中它自己的“沙盒”中操作。相 比较来说,在开放式平台(如智能电话)每个可执行程序可以运行于 自己的进程中,通常这种开放式平台的操作系统可以将设备的所有 功能开放给每个运行的进程使用。此外,有些环境(如Brew)只允 许RTE应用通过网络加载,禁止应用通过存储卡的方式加载进设 备。当要加载大型应用时就会有问题,例如大型游戏,通过网络加 载需要大量的带宽和时间。
在此描述的系统和方法通过为封闭式平台提供增加功能的方式 改善现有方法的
缺陷。在说明性实现中,增加的功能以PIDL的方式 提供给硬件设备。封闭式平台创建时可以包含“启动”程序,它包含 前面提到的动态链接程序/加载程序和与PIDL协作的应用。创建的 启动程序可以在封闭式设备内为主操作系统创建并运行,可以在设 备发货时就驻留在设备内部。如下所述,启动程序加上PIDL库允许 为该封闭式设备增加新的功能,即使增加的功能在设备发货时没有 自带。在运行期,该PIDL可以供设备和启动应用启动时使用。启动 应用内部的动态链接程序/加载程序,响应启动程序在运行期调用 PIDLOpen打开PIDL库,可以加载、链接和绑定该PIDL到协作的启 动程序,该启动程序驻留在硬件设备中,运行于设备操作系统之 上。接着,通过动态链接程序/加载程序提供的GetPIDLAddress函 数,PIDL内的所有函数因此可以被暴露给设备中运行的程序,因此 达到所期望的结果,即给封闭式设备增加新功能。这样,该PIDL绕 过了硬件设备强制的限制,使得可以动态运行(如前面所述)。
要理解“启动”应用本身可以提供一组功能,其操作不依赖于 PIDL的存在。类似的,同一处启动应用可以支持许多不同类型的新 功能,每个功能在不同的PIDL库中提供,它可以被启动应用打开。 使用所说明性实现,使得模拟某种运行期的环境成为可能,其中不 同功能可以动态增加进去。
通过说明性的例子,启动应用可以包含游戏终端软件和一个或 多个游戏。更多的游戏可以以PIDL库的形式添加,每个游戏一个 PIDL,当PIDL下载进设备后就可以通过启动应用玩。或者,启动 应用可以提供基本的消息功能,比如短消息系统(SMS)。更多功 能,比如email或多媒体消息、视频和音频播放、PIM(个人信息管 理)以及其它类型的功能可以以PIDL库的方式在设备中部署,它们 与启动程序交互操作。
在另一个演示实现中,封闭式设备发货时可以包含两个或多个 “启动”应用,每个识别一组特定的PIDL库。用这个方法,就能显著 地方式扩展和组织功能增加的范围。
在此描述的方法和系统在封闭式平台上应用时克服了封闭式平 台现有方法的缺点。提供售后解决方案的可能性为设备用户创造了 更大的使用性,为设备或网络提供商增加了收入机会。由于该方法 不涉及增加可执行文件形式的功能(例如,PIDL库可以是数据而不 用是可执行文件),平台的“封闭”性得到控制,因为它对于为设备操 作系统创建的可执行文件形式的普通应用而言依然保持封闭。设备 提供商可以预先决定要提供的功能扩展范围,因为只有启动程序打 开的PIDL库包括中的函数时可操作的。结果可以是一组动态安全和 商业控制。
在说明性实现中,PIDL可以以多种方式提供给设备,包括:通过 无线或有线网络下载,从PC上连线传输数据,和通过插入的存储卡 传输到设备中。将PIDL以对象而不是可执行应用的形式加载还有一 个独特的方面就是PIDL可以通过数字
版权管理(DRM)技术保护。 作为数据文件的PIDL经得起DRM技术的检验,这和可执行程序不 同。这种完好的安全方案在商业协议下增加功能可以同时为运营商 和用户提供灵活性和可靠性。
如上所述,当将PIDL对象的平台无关性和链接方案组合起来, 设备制造商或网络提供商就能够通过单一的PIDL对象为他们所有设 备产品线提供附加功能,即使这些设备使用了不同的主机平台或操 作系统。通过避免了为每个不同的平台定制应用或库,而只是简单 得提供在所有平台上同样工作的平台
开关动态库(PIDL),运营商 将大规模得实现效率和节约。
上面针对封闭式平台(如特性电话)描述的方法和系统同样可以 应用于支持运行期环境的平台(例如,Java或Brew)。这种安排为 设备提供了两种增加功能的方法——传统方案下载applet或由RTE 使用的授权应用,另一实现方案是在设备内驻留的启动应用的控制 下加载PIDL功能库。
相比于这两种方案,基于PIDL的方案可以提供在传统运行期环 境中不存在的附加特性。换种说法,当单一启动应用使用多个分开 的PIDL时,多个功能就可以同时运行。这样,使用PIDL实现, PIDL的功能就可以在共同的启动进程下执行,且因此可以同时运 行。此外,通过PIDL加载方法,使得在设备上加载功能的方式有更 大的灵活性,包括从存储卡加载,这种方式在特定的运行期环境(如 Brew)是不允许的。对于DRM,在部署PIDL
数据库时可以实现 DRM,此技术在运行期环境中部署可执行应用或applet是不可用 的。同时,如果需要,设备或网络提供商还可以限制可增加的功 能,使发货的设备中的启动应用只识别被允许的功能。
与启动程序在创建时被包含进去的严格封闭式环境不同,拥有 运行期环境(RTE)的设备可以利用在发货后下载启动应用的优势。 当使用这种方式时,上述的基于动态库(DL)的方案可以与RTE共 存,同时提供RTE自身无法提供的优点。具体来说,DL库可以访问 通过RTE无法访问的设备功能和API(如存储卡)。使用这种方案, 启动应用就可以穿过通信网络下载到设备的RTE,其中启动程序作 为代理允许通过其它方式,比如存储卡,增加更多功能。类似的, RTE常常限制在RTE下运行的应用的最大大小。通过下载本身很小 的启动应用,其大小在限定的范围内,但添加的含有功能代码的DL 库却可以超越大小限制,这样可以绕过最大大小,以使设备可以使用 更大的程序。因为DL库是作为二进制数据对象而不是作为RTE应 用加载的,RTE的大小限制不针对它。
图13展示了示例计算环境处理PIDL以在封闭式计算环境中实 现动态执行的处理过程。(相同的过程也适用于具有传统运行期环境 的封闭式环境和开放式计算环境)。如图13所示,处理从块1300开 始,其中功能被分成两部分,一部分是设备发货时(未示出)在设备 内驻留的启动应用中提供的自带功能,另一部分作为附加功能提 供。
在图13所示的说明性实现中,PIDL库对象在块1320中创建, 它含有附加功能。启动应用在块1310中编译创建,其中含有从块 1300中的自带功能,还有动态链接程序/加载程序和在该PIDL从启 动应用导入符号时可选的PIDL_getSymbol源码。如块1340中所示, 启动程序可以在设备发货时就包含在设备中。
设备发货后,在块1350中可以提供采用附加功能的授权。就像 可理解的那样,授权可以基于商业协议,或者其它根据设备使用情 况的标准。在授权后,在块1360,PIDL库可以通过合适的方式提供 给设备使用,方式可以包括但不限于:下载到设备存储器,网络传 输,或从存储设备或设备链接的卡提供。然后在块1370中设备中的 启动应用可以运行。在执行期间,启动应用在块1375中调用 PIDLOpen来打开PIDL库。然后在块1380执行检查,决定是否有 PIDL可供设备使用。这个检查可以通过启动应用中的动态链接程序/ 加载程序使用在块1375中提供的PIDLOpen调用。如果块1380的检 查表明没有PIDL可供设备使用,处理前进至块1385,其中启动应用 继续执行,但只是在设备自带的功能中运行(即,不执行PIDL包含 的附加的功能)。
但如果块1380的检查表明有PIDL库可供设备使用,处理前进 至块1390,其中PIDL被加载、链接和绑定到启动应用中。通过这个 步骤,启动应用可访问的功能范围得到扩展,如块1395所示,包括 该PIDL提供的功能。这些导出函数可以通过前面描述的在块1310 中编译的动态链接程序/加载程序提供的GetPIDLAddress机制访问。
图14展示了通过下载启动应用提供附加功能的处理过程。该过 程可以在示例的计算设备发货后发生,与下载到开放式环境或下载 启动应用与设备上现有的RTE一起操作的情况类似。该过程还可以 作为独特事件发生,其中下载应用到封闭式环境中,环境对于下载 或增加的其它计算应用(例如,启动应用之外的应用)还保持封闭状 态。启动应用可以通过技术或商业控制的方式(例如下载)操作。
如图所示,处理开始于块1400,其中程序被分成启动应用和附 加功能。然后处理分开至块1415或1405。在块1405中,附加功能 的动态库(DL)对象被创建。在块1415中启动应用、链接程序/加载 程序和在该PIDL从启动应用导入符号时可选的PIDL_getSymbol源 码被编译和创建。从块1405开始,处理进一步分叉。从块1405起, 处理可以前进至块1445,其中DL被提供给协作设备(如移动电 话)。从块1445起,处理前进至块1460,块1460在下面讨论。
从块1415起,处理前进至块1420,其中启动应用被下载至设 备。然后在块1425执行检查,决定下载的启动应用是否被授权在下 载的设备上操作。如果块1425的检查表明该启动应用没有授权,处 理在块1440结束。但如果块1425确定该启动应用被授权在该设备上 操作,处理前进至块1430,其中启动应用运行。在执行期间,启动 应用在块1435调用PIDLOpen打开PIDL库。然后在块1450执行检 查,决定该DL是否通过前述的块1445可供设备使用。如果块1450 的检查表明没有DL可供设备使用,启动应用的范围保持在发货时的 范围,不扩展如块1445由DL提供的附加功能。但如果块1450的检 查表明有DL可供设备使用,处理前进至块1460,其中链接程序/加 载程序加载DL,将它与运行的应用绑定。处理前进至块1465,其中 启动应用的范围扩展到包括导出的DL函数,然后从那继续。这些导 出的函数可以通过上面描述的在块1415中编译的动态链接程序/加载 程序提供的GetPIDLAddress机制访问。
要理解图14描述的过程可以应用于下载单个启动应用或下载多 个启动应用。这种启动应用可以根据该启动应用运行时被该启动应 用打开的库操作增加选定的函数。
总之,在此描述的设备和方法提供可以跨越不同计算环境、操 作不同平台的平台无关二进制对象。但要理解,本发明可以有不同 的修改和替换构造。本发明不限于在此描述的特定构造。相反,本 发明意在涵盖所有的修改、替换构造和在本发明范围和精神之内的 等价构造。
还要注意的是本发明可以在不同的计算机环境中实现(包括非无 线和无线计算机环境)、局部计算环境和实际环境。在此描述的不同 技术可以在硬件或软件中实现,或结合两者实现。所述技术优选在 如下计算环境中实现,其中计算环境维护可编程计算机,其中包括 处理器、处理器可读的存储媒介(包括易失和非易失的存储器和/或 存储器件)、至少一个输入设备和至少一个输出设备。计算硬件逻辑 与不同指令集协作一起应用到数据上,执行上述功能和生成输出信 息。输出信息被应用于一个或多个输出设备。被示例计算硬件使用 的程序可以以不同的编程语言实现,包括高级过程或面向对象编程 语言,来和计算机系统通信。如果愿意,在此描述的示例性设备和 方法可以以汇编或机器语言实现。无论何种情况,该语言可以是编 译性或解释性语言。每个计算机程序优选存储在存储媒介或设备(例 如,ROM或磁盘)上,它们可以被通用或专用可编程计算机读取, 以配置和操作计算机来执行上述操作。该设备还可以考虑实现成计 算机可读存储介质,通过计算机程序配置,其中存储媒介配置成使 得计算机以特定和预定的方式操作。
虽然本发明的示例实现已经在上面进行了详细描述,但本领域 的技术人员可以理解,在说明性实施例中可以进行许多额外修改而不 实质性脱离本发明的新颖主旨和优势。相应的,这些以及所有这种 修改也被包括在本发明的范围之内。本发明由
权利要求更好地定 义。