运行期动态链接的制作方法

文档序号:6657094阅读:261来源:国知局
专利名称:运行期动态链接的制作方法
技术领域
本发明涉及二进制对象的创建和操作,更确切的说,涉及能在不同计算机环境上运行的平台无关二进制对象的创建、操作和发布,支持不同非本地计算环境操作。
背景技术
计算环境能够执行为该计算环境的硬件组件设计的,包含一条或多条指令的计算机代码,以执行一个或多个操作。通常计算机代码要加载到计算环境中执行。在物理加载前,计算机代码可以被编译以使之能够在特定的计算环境中操作(例如,计算环境操作系统和/或计算环境平台)。计算机代码能被计算环境链接到驻留在该计算环境中的其它计算机代码中,以执行一个或多个操作。根据计算环境对给定计算机代码的处理方式,可以创建二进制对象给该计算环境使用和/或与其它计算机代码协同操作。该二进制对象可能包含一个或多个协同计算程序(计算程序)需要的信息、函数和/或操作。
进而,一个或多个函数可以聚合到一个或多个库中,以便为计算应用程序、其它库或计算环境所使用,以执行一个或多个操作。在通常的实践中,设计实现的库可以被拥有特定硬件体系结构的单个计算环境使用。库能够基于静态或动态库的形式被计算环境使用。在静态背景下,给定计算应用的库和其它组件被联合到单个文件中,它能够被加载至存储器执行。相对的,动态操作(例如,动态链接组件)函数和组件(例如,对象和库)被设计成在计算应用执行时使用。动态组件能够在计算环境上的多个计算应用中共享,因为动态链接的组件在设计和操作上不与计算应用的主要部分绑定。
但是,当前的实践在创建和执行为不同计算环境使用的计算机代码时很麻烦。因为当前的实践通常要求为具有特定计算硬件架构的特定计算环境创建和执行代码(例如,通过软件开发包-SDK),为数个不同计算环境(例如,拥有不同操作系统和/或计算平台)创建单个二进制对象很困难。当为特定计算环境创建代码时,计算机代码能够在加载到计算环境之前预先编译,在执行计算机代码时被计算环境链接。由于这些限制,计算机代码通常只为单一计算环境(即操作系统和/或平台)设计和创建。
另外,计算环境会对计算机代码创建的方式施加限制和规则,从而使之在给定的计算环境中能够正确的执行。例如,平台和/或操作系统(例如,运行Symbian Quartz的SymbianOS)对在该特定平台和/或操作系统上执行的计算机代码施加数个限制,包括但不限于,对可写静态和/或全局变量的使用。换句话说,平台和/或操作系统可以禁止具有可写静态和全局变量的计算机代码。
在计算机代码开发人员中普遍的实践包括但不限于,开发各种执行相同操作的代码,但是这些代码要针对每个不同的操作系统和平台进行构建。例如,可以使用单一高级编程语言来开发日历计算应用,比如Java,C++或Visual Basic。为了减少开发时间和资源,核心计算应用代码可以被开发人员重复使用。但是,这种重用的范围有限,因为当前实践中需要开发和定制额外的组件(例如,库、函数、数据结构等)以确保计算应用在每个不同的计算环境(例如,操作系统和/或平台)中都可操作。
传统实践和方法还有其它限制,包括但不限于,无法使单个平台无关的二进制对象无需为每个不同计算环境重建或重新编译而跨不同计算环境操作。此外,当前的实践和方法在不提供本地支持的平台中没有提供用于共享对象的动态链接的机制。同时,在当前实践中,预先编写的代码组件可能由于违反特定代码中的平台限制产生不兼容,从而无法在平台中使用。此外,当前实践没有为非面向对象代码的加载提供机制,非面向对象代码可以绕过多执行实例和代码内在的循环执行的限制。同时,当前实践和方法没有提供在封闭式平台(例如,限制执行附加程序的平台)中允许动态链接和加载二进制对象的机制。

发明内容
在此描述的系统和方法提供了能够在拥有选定硬件架构的不同计算环境中操作的平台无关的二进制对象(PIBO),而无需重新编译、重建或重新加载。在示例的实现中,提供的二进制对象拥有选定的结构(例如,对象文件格式)。该二进制对象文件能够通过编译源代码创建,当源代码被创建时不具有平台依赖性。在示例实现中,二进制对象文件包括用于源文件的二进制代码和数据。此外,提供作为示例的计算应用一部分的示例链接程序/加载程序,其使用该桩文件链接和加载该平台无关二进制对象,使之允许与不同计算环境中的计算程序协作。同时,还提供示例接口允许协作计算应用访问例子中的PIBO。
在示例的操作中,示例性链接程序/加载程序可以连同协作计算应用的主源代码为不同的计算环境中的一个进行编译,以产生在不同计算环境中的一个上可执行的二进制文件。在说明性实现中,在该协作计算应用执行时,示例的链接/加载程序能够将该PIBO链接和加载到协作计算应用中。在示例的实现中,该链接/加载程序能够处理符号的解析和重定位,将协作计算应用的二进制执行对象与该PIBO绑定在一起形成一个整体的可运行进程。
在示例的实现中,所述PIBO能够在不同的背景中使用,包括但不限于,作为不提供本地设施的平台上动态链接共享对象的机制;利用在平台上预写好的代码组件,该特定代码本来由于违反平台限制而不兼容;作为加载非面向对象的代码的机制,该非面向对象的代码绕过多执行实例和重复执行代码的限制;以及作为允许使用的二进制对象为封闭式平台提供附加功能的机制。
本发明的其它特性将在下面继续深入探讨。


平台无关的动态对象和使用方法通过结合附图进行详细描述,其中
图1是根据所描述的系统和方法的实现的示例计算环境框图;图2的框图示出示例数据通信架构的示例组件的协作;图3是动态链接架构的框图;图4是在将相同的库链接到第一个不同计算平台操作系统时的动态链接架构框图;图5是在将相同的库链接到第二个不同计算平台操作系统时的动态链接架构框图;图6是支持根据在此描述的系统和方法的多个平台的多个操作系统的框图;图7中的框图显示的是根据在此描述的系统和方法的平台无关链接架构的示例平台中各个示例组件间的交互;图8中的框图显示的是根据在此描述的系统和方法的主要应用程序和动态库之间的交互;图9显示的是根据在此描述的系统和方法的平台无关链接架构的示例平台执行的处理流程图;图10显示的是在没有本地设施支持的计算环境中动态链接平台无关的二进制对象时执行的处理流程图;图11显示的是在受限计算环境中使用平台无关二进制对象时执行的处理流程图;图12显示的是在受限计算环境中使用平台无关二进制对象运行协作计算应用的多个实例的处理流程图;图13显示的是在封闭式硬件环境上使用平台无关二进制对象扩展功能时执行的处理流程图;以及图14显示的是根据在此描述的系统和方法的示例实现的受限计算环境中通过下载启动应用以提供扩展功能时执行的处理流程图。
具体实施例方式
1、概述计算机代码能够在计算机系统或设备内的中央处理器(CPU)或其它计算处理器上执行。常见的CPU架构包括但不限于,INTELx86系列、ARMRISC(精简指令集代码)架构、SUNSPARC和MOTOROLA68000。代码可以写成人类能够理解的高级程序语言,比如C、C++或JAVA,但最终这些代码会被计算环境编译和汇编成在示例计算机处理器上执行的机器指令。
CPU可以处于软件环境中,该软件环境通常被称作系统平台。该平台可以包括操作系统,比如为更大型计算环境设计(例如,桌面系统、膝上个人计算机)的MICROSOFTWINDOWS和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。CPU110可以通过互连器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通常包含存储的不能修改的数据。存储在RAM125的数据可以被CPU 110或其它硬件设备读取或修改。对RAM125和/或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得到的对象文件静态链接以创建所到的动态可执行对象文件A1exec435(例如,在平台A1 475上可执行)。同样,如图所示,编译425得到的对象文件被静态链接,创建得到动态执行对象文件A2exec440(在平台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中被编译以为操作系统B585创建动态库(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被加载进操作系统B585的地址空间中,以创建运行于平台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或A2exec440中,以在各个平台A1 475和A2 480中创建可运行进程。
图5示出了两个额外的可执行文件B1exec 535和B2exec 540被编译以允许应用在平台B1 575和平台B2 580上运行。此外,创建新的动态库530以与可执行文件B1exec 535和B2exec 540链接,因为可执行文件B1exec 535和B2exec 540是为操作系统B 585构建的。在此实现中,为了实现跨越运行于两个操作系统(分别是操作系统A485和操作系统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的共同性。
在此描述的系统和方法可以应用到不同的计算环境中。在示例性实现中,在此描述的系统和方法可用于桌面系统,它通常包含INTELx86家族的处理器。桌面PC的通用操作系统是微软的WINDOWS和Linux,两者都有动态链接功能。但是这些操作系统为它们的二进制对象使用了不兼容的格式,因此需要为Linux和WINDOWS提供不同的二进制文件,尽管它们运行在相同的CPU上。
在移动和嵌入式设备上,多样性问题可能更显著。具体而言,移动和嵌入式设备使用更多数量的操作系统,包括但不限于,Linux、WINDOWSCE、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或磁盘)上,它们可以被通用或专用可编程计算机读取,以配置和操作计算机来执行上述操作。该设备还可以考虑实现成计算机可读存储介质,通过计算机程序配置,其中存储媒介配置成使得计算机以特定和预定的方式操作。
虽然本发明的示例实现已经在上面进行了详细描述,但本领域的技术人员可以理解,在说明性实施例中可以进行许多额外修改而不实质性脱离本发明的新颖主旨和优势。相应的,这些以及所有这种修改也被包括在本发明的范围之内。本发明由权利要求更好地定义。
权利要求
1.在计算环境内操作的软件平台上动态加载和链接二进制对象文件的系统,包括动态库(DL);以及动态加载程序/链接程序,与协作计算应用编译和创建,以生成在所述软件平台上执行的二进制可执行程序,所述加载程序/链接程序包括打开所述DL的第一函数和返回由所述DL导出的符号在存储器中的地址的第二函数,从而允许所述计算应用在运行时访问所述DL并和所述DL协作。
2.根据权利要求1的系统,其中所述DL包含具有选定的结构的二进制对象文件。
3.根据权利要求2的系统,其中所述DL选定结构包括可执行和链接格式(ELF)和可移植可执行(PE)格式中的任一个。
4.根据权利要求2的系统,其中所述动态加载程序/链接程序操作所述DL,响应于所述协作计算应用中执行所述第一函数以打开所述DL的指令,在运行期将所述DL加载至所述软件平台。
5.根据权利要求4的系统,其中所述动态加载程序/链接程序确定所述DL对象文件的大小。
6.根据权利要求5的系统,其中所述动态加载程序/链接程序分配存储器以在所述软件平台上加载所述DL对象。
7.根据权利要求4的系统,其中所述动态加载程序/链接程序操作所述DL,在运行期将所述DL与所述协作计算应用链接。
8.根据权利要求4的系统,其中响应于所述协作计算应用中执行所述第二函数的指令,返回由所述第一函数打开的所述DL导出的符号的所述地址。
9.根据权利要求2的系统,其中单个二进制对象文件跨越一确定的处理器架构上执行的多个软件平台和操作系统而被动态加载和链接,而无需重新编译或重建所述二进制对象文件。
10.根据权利要求9的系统,其中用于与所述DL协作的计算应用的源代码和所述动态加载程序/链接程序的源代码,被编译并链接成所述多个软件平台中选定的一个的二进制可执行程序。
11.根据权利要求4或7的系统,其中所述DL被动态加载和链接至对所述DL的二进制格式不提供本地支持的操作系统上操作的计算环境的计算应用。
12.根据权利要求1的系统,其中所述DL被动态加载链接至没有用于执行对二进制对象的动态链接的本地动态链接机制的操作系统上操作的受限计算环境的计算应用。
13.根据权利要求2的系统,进一步包括接口模块,该接口模块为所述DL提供对所述协作计算应用的访问。
14.根据权利要求13的系统,其中所述接口模块包含允许所述DL调用所述协作计算应用中选定函数的源代码。
15.根据权利要求14的系统,其中所述接口模块的源代码通过解析所述协作计算应用的应用编程接口而生成。
16.根据权利要求14的系统,其中所述接口模块的源代码通过解析所述DL二进制对象文件以识别由所述DL导入的符号而生成。
17.根据权利要求14的系统,其中所述接口模块的源代码、所述协作计算应用的源代码和所述动态加载程序/链接程序的源代码为所述软件平台进行编译。
18.根据权利要求7的系统,其中所述动态加载程序/链接程序处理符号的分解和重定位,以将所述协作计算应用与所述DL绑定至所述软件平台上的可运行进程。
19.根据权利要求18的系统,其中所述可运行进程包括与多个动态库协作并绑定至所述多个动态库的计算应用。
20.根据权利要求18的系统,其中所述动态加载程序/链接程序在将文件链接至所述协作应用时区分DL文件和非DL文件。
21.根据权利要求20的系统,其中所述可运行进程将所述协作计算应用链接至所述DL和所述软件平台本地的动态链接库。
22.根据权利要求1的系统,其中库源代码被编译以生成包含二进制代码和/或数据的所述DL。
23.根据权利要求22的系统,其中所述DL被动态加载并链接至在所述软件平台上执行的二进制可执行程序,其中所述库源代码包含违反所述软件平台编程限制的代码。
24.根据权利要求23的系统,其中所述编程限制包含对全局变量使用的限制,或对可写静态变量使用的限制,或对指针变量的静态初始化的限制。
25.根据权利要求24的系统,其中所述动态加载程序/链接程序在所述DL链接的所述程序执行期间,分配存储器块以加载所述DL对象到所述软件平台。
26.根据权利要求25的系统,其中所述动态加载程序/链接程序用于将所述库中定义的所述全局或可写静态变量的范围限定至所述DL占据的所述存储器块。
27.根据权利要求17的系统,其中所述库源代码包括以限制多个执行实例或代码的重复执行的方式处理数据和为数据提供访问函数的代码;以及所述动态加载程序/链接程序加载所述库的实例至动态分配的存储器块中,其中在所述库代码中定义的所述数据变量的范围被限定至所述存储器块内。
28.根据权利要求27的系统,其中同一个所述库的多个不冲突实例可在所述计算环境中执行。
29.根据权利要求27的系统,其中由所述DL使用的数据通过所述代码内定义的全局变量或静态变量而被引用。
30.根据权利要求27的系统,用于加载非面向对象代码,以允许单个计算环境进程中的多个执行实例。
31.根据权利要求30的系统,其中多组库数据可以在单个计算环境进程中同时操作,这样每组所述库数据之间的冲突被减少和/或消除。
32.根据权利要求27的系统,用于加载非面向对象代码,以允许在单个计算环境进程内重复执行所述代码。
33.根据权利要求27的系统,用于加载代码,以在不支持多进程的计算环境中允许多个执行实例和重复执行所述代码。
34.根据权利要求2的系统,其中所述计算环境受到在所述计算环境中部署非驻留的可执行程序的限制,所述协作计算应用包括启动应用,用于通过动态链接所述DL至执行的启动应用来扩展所述受限计算环境可用的功能。
35.根据权利要求34的系统,其中所述受限计算环境不允许增加所述计算环境的本地可执行程序。
36.根据权利要求34的系统,其中所述计算环境对可在所述计算环境中执行的程序的最大大小有限制。
37.根据权利要求34的系统,其中所述计算环境支持运行期环境(RTE)。
38.根据权利要求37的系统,其中运行在所述RTE中的所述程序具有对所述本地计算环境可用的一个或多个函数的受限访问。
39.根据权利要求37的系统,其中所述RTE限制操作以只运行被所述RTE授权的程序。
40.根据权利要求37的系统,其中所述RTE包括Java 2移动版本(J2ME)RTE和无线二进制运行期环境(BREW)RTE中的任意一种。
41.根据权利要求34的系统,其中编写所述启动模块以作为所述计算环境上的本地计算应用而运行。
42.根据权利要求37的系统,其中编写所述启动程序以作为所述计算环境的所述运行期环境中的计算应用而运行。
43.根据权利要求41的系统,进一步包括至少两个启动模块。
44.根据权利要求34的系统,其中所述DL被存储在物理上与所述计算环境分开的存储介质中,所述存储介质包括闪存单元、固定存储器单元和微驱动器中的任意一种。
45.根据权利要求34的系统,其中包含所述启动应用的所述二进制可执行程序被存储在物理上与所述计算环境分开的存储介质中,所述存储介质包括闪存单元、固定存储器单元和微驱动器中的任意一种。
46.根据权利要求34的系统,其中所述DL在数字版权管理方案下使用,以促进在所述受限计算环境中内容的安全发行。
47.在计算环境中操作的软件平台上集成二进制对象的方法,包括如下步骤提供库源代码;编译所述库源代码,以生成包含具有选定格式的对象文件的代码库(CL);编译并构建动态加载程序/链接程序的源代码和与所述库协作的计算应用的源代码,以生成在所述软件平台上执行的二进制可执行程序;以及从所述协作计算应用内部打开所述代码库。
48.根据权利要求47的方法,进一步包含选择包括ELF文件格式或PE文件格式的对象文件格式的步骤。
49.根据权利要求47的方法,进一步包括由所述动态链接程序/加载程序分配存储器块以在运行期将所述CL动态加载进计算环境存储器中。
50.根据权利要求48的方法,进一步包含在所述动态链接程序/加载程序中提供打开所述CL的第一函数和返回由所述CL导出的符号在存储器中的地址的第二函数,从而允许所述计算应用在运行期访问所述CL并和所述CL协作。
51.根据权利要求50的方法,进一步包含响应于所述协作计算应用中执行所述第二函数的指令,返回由所述第一函数打开的所述CL导出的符号的所述地址的步骤。
52.根据权利要求47的方法,进一步包含提供源代码形式的接口模块源代码的步骤,该接口模块为所述CL提供访问以调用所述协作计算应用中的选定函数。
53.根据权利要求52的方法,进一步包含将所述接口模块的源代码、所述协作计算应用的源代码和所述动态加载程序/链接程序的源代码编译成在所述软件平台上执行的二进制可执行程序的步骤。
54.根据权利要求47的方法,进一步包含跨越多个在一确定的处理器架构上执行的软件平台和操作系统集成单个二进制对象文件,而无需重编译或重建所述二进制对象文件的步骤。
55.根据权利要求54的方法,进一步包含将用于与所述CL协作的计算应用的源代码和所述动态加载程序/链接程序的源代码编译并链接成为多个软件平台中选定一个的二进制可执行程序的步骤。
56.根据权利要求47的方法,其中所述计算环境对所选对象格式不提供本地支持。
57.根据权利要求47的方法,进一步包含加载所述CL,并将其链接至受限计算环境中的计算应用的步骤,所述计算应用在不提供执行二进制对象的动态链接的本地动态链接机制的操作系统上操作。
58.根据权利要求49的方法,其中所述库源代码包含违反所述软件平台的编程限制的代码。
59.根据权利要求58的方法,其中所述编程限制包含对全局变量使用的限制、对可写静态变量使用的限制和对指针变量的静态初始化的限制中的任意一个。
60.根据权利要求59的方法,进一步包含将所述库中定义的所述全局或可写静态变量的范围限定至所述CL占据的所述存储器块的步骤。
61.根据权利要求47的方法,其中所述库源代码包括以限制多个执行实例或代码的重复执行的方式处理数据和为数据提供访问函数的所述代码;以及其中所述方法进一步包含如下步骤所述动态加载程序/链接程序加载所述库的实例至动态分配的存储器块中,其中在所述库代码中定义的所述数据变量的范围被限定在所述存储器块。
62.根据权利要求61的方法,进一步包含在单个计算环境进程中加载待执行的同一库的多个不冲突实例的步骤。
63.根据权利要求62的方法,其中多组库数据可以在单个计算环境进程中同时操作,这样每组所述库数据之间的冲突减少和/或消除。
64.根据权利要求61的方法,进一步包含加载非面向对象代码,以在单个计算环境进程内重复执行所述代码的步骤。
65.根据权利要求62或64的方法,其中所述计算环境不支持多个进程。
66.根据权利要求47的方法,其中所述计算环境受到在所述计算环境中部署非驻留可执行程序的限制;以及其中该方法进一步包含下列步骤通过动态链接所述协作计算应用中包含的执行启动应用与所述CL来扩展所述受限计算环境可用的功能。
67.根据权利要求66的方法,其中所述计算环境受到包括下列一个或多个的一个或多个限制所述计算环境对于增加本地可执行程序是封闭的;所述计算环境限制于执行在程序大小限度范围内的程序;所述计算环境具有运行期环境(RTE),其中在所述RTE中运行的程序具有对所述本地计算环境可用的一个或多个函数的受限访问;所述计算环境具有RTE,其限制操作只运行被授权用于所述RTE的程序;以及所述计算环境不允许动态链接。
68.分发在一确定的处理器架构上运行的不同计算软件环境中使用的计算库的方法,包含如下步骤创建具有选定结构的二进制对象文件的动态库(DL);通过编译动态链接程序的源代码和可以在至少一个所述计算环境上运行的协作计算应用的源代码,构建二进制可执行程序;从包含任意通信网络和存储介质的输入源中传输所述DL至不同的计算环境;以及动态连接所述DL和所述二进制可执行程序。
69.根据权利要求68的方法,进一步包含传输与至少一个DL协作的所述计算应用的新版本的步骤。
70.根据权利要求68的方法,进一步包含传输与所述计算应用协作的所述DL的新版本的步骤。
71.根据权利要求68的方法,用于分发计算库给计算环境使用,其中所述计算环境受到包括下列一个或多个的一个或多个限制所述计算环境对于增加本地可执行程序是封闭的;所述计算环境限制于执行在程序大小限度范围内的程序;所述计算环境具有运行期环境(RTE),其中在所述RTE中运行的程序具有对所述本地计算环境可用的一个或多个函数的受限访问;所述计算环境具有RTE,其限制操作只运行被授权用于所述RTE的程序;以及所述计算环境不允许动态链接。
72.根据权利要求71的方法,进一步包含下载协作启动应用到计算设备中的步骤,所述协作启动应用作为代理以允许所述启动程序访问来自包含通信网络和存储介质中的任意一个的输入源的所述计算设备可用的动态库。
73.根据权利要求72的方法,进一步包含当动态库能被所述计算设备使用时,扩展所述启动应用的范围,使之包括协作动态库的附加功能的步骤。
74.根据权利要求68的方法,其中所述协作计算应用在所述计算设备被销售发货交给最终用户之前就被部署在所述计算设备的计算环境中。
75.根据权利要求68的方法,其中所述协作计算应用在所述计算设备被销售发货交给最终用户之后被部署在所述计算设备的计算环境中。
76.根据权利要求74或75的方法,其中所述计算设备是移动电话或无线手持设备。
77.根据权利要求68的方法,其中所述DL在数字版权管理方案下使用,以促进内容被安全发行到所述计算环境上。
全文摘要
提供一种与平台无关的二进制对象(PIBO),其可以在特定硬件体系结构的不同计算环境中执行,而无需重编译或重加载。该PIBO可以通过示例链接程序/载入器与协作计算应用一起编译和创建并与协作应用一起编译和创建。同时,该PIBO还可以在不同的背景下使用,包括但不限于,作为不提供本地支持的平台上提供动态链接共享对象的机制;利用平台上预写好的代码组件,该特定代码本来由于违反平台限制而不兼容;作为加载非面向对象的代码的机制,从而绕过多执行实例和重复执行代码的限制;以及作为允许使用的二进制对象为封闭式平台增加功能的机制。
文档编号G06F9/445GK101040259SQ200580034911
公开日2007年9月19日 申请日期2005年9月21日 优先权日2004年10月12日
发明者马希德·安瓦尔, 保罗·加德纳 申请人:皮克塞(研究)有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1