跨平台软件的开发方式.doc_第1页
跨平台软件的开发方式.doc_第2页
跨平台软件的开发方式.doc_第3页
跨平台软件的开发方式.doc_第4页
跨平台软件的开发方式.doc_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

跨平台软件的开发方式2007年04月15日 星期日 09:48原创:smalltalk随着经济和技术的发展,全球化进程的加速,特别是互联网的发展和普及,为软件提供了一个世界范围的运行环境,当一个软件发布到Internet上面时,这个软件很可能瞬间在全世界就被人使用。从软件开发商的角度来看,同时具有跨平台和全球化特性的软件能够最大限度的占有市场;从自由软件开发团体和个人来看,开发的软件不但能够运行在多种操作系统下,而且还能够以不同的语言版本运行,全世界用户都可以使用,这本身就符合自由和开放的追求。由于这些因素,跨平台技术和全球化技术一直是软件业研究和发展的重要课题。开发跨平台软件和全球化软件的最大目的是为了争取更多的用户,获得更大的市场。跨平台软件能够在多个不同类型的操作系统下运行,它从操作系统层次拓宽软件的用户群体;全球化软件是既具有国际化特性又进行了本地化处理的软件,这样,世界上不同国家和地区的用户都能以自己熟悉的语言和习惯来使用该软件。具有跨平台特性的全球化软件是非常有“魅力的”,它能够吸引到更多的潜在用户。由于跨平台和国际化两者都是特别广泛的概念,不同的软件架构、不同的开发语言,采用的方法各不相同,为了做到不以偏概全,本篇文章将主要针对那些采用C/C+语言进行开发的、并准备添加或者已经具有跨平台特性的、同时还需要全球化的软件。文章为开发者在设计和实现这类软件时提供一些指导性意见,给出一些针对跨平台软件实施全球化的方法,并提出了一种采用跨平台资源文件和模块配合的解决方案和具体实现。*什么是跨平台软件跨平台软件技术在过去的十几年来逐步发展,特别是当个人计算机(PC & MAC)性能的提高,LINUX操作系统的出现,JAVA语言的推出,呈现出跳跃发展的趋势。目前不但很多著名的自由软件项目提供跨平台的自由软件,而且很多专业的软件厂商也将他们的产品向不同的平台移植。在发展的历程中,跨平台软件技术也逐步形成规范,但由于平台固有的异质性,在进行跨平台软件开发时,往往在软件的功能、效能与移植性等之间,要做适当的权衡,比较难整理出一般性的、与平台及工具种类无关的法则。什么是跨平台软件,简单讲就是至少可以运行在两个不同操作系统平台下的软件,完成相同或者相似的功能,而且这个软件的可执行程序来自与一份源代码。*跨平台软件的开发方式跨平台软件的开发方式大体有三种,第一种是先在一个基准平台上开发好,然后再移植到其他的操作系统;第二种是采用的跨平台模块组合;第三种是采用虚拟机技术,利用平台无关的语言进行开发。1. 移植第一种开发方式是比较传统的做法,也是一直被广泛采用的方式。这种做法也称为软件移植(Porting),即把在一种操作系统下运行的软件通过改写部分代码,移植到另外一种或多种操作系统下运行。软件最初的设计、编码以及移植时使用的工具,这些决定了移植的代价。如果软件在最初的设计、编码时没有考虑到以后的移植,大量采用了平台相关的技术和平台相关框架库进行编码,对这些代码移植将付出极高的代价。一种极端的情况是最初使用的开发语言不能跨平台的,以后要对这个软件进行移植,将不得不更换开发语言重新编写全部代码,还要进行全新的测试,这样的软件在移植时是异常困难的。1.1. 宏定义软件的代码,从跨平台的角度来看,可以分为平台相关的和平台无关的。采用C/C+编写的软件,在进行移植时,平台无关的的代码基本上不需要做大的改动,但平台相关的代码需要做很大的调整。这里所说的平台包括操作系统和编译器,为了能够做到让编译器在编译时根据当前的平台状况来自动选择需要编译的代码,我们一般需要用C/C+的编译宏指令来实现。举个例子,下面的一段代码是得到系统当前的时间并且格式化成字符串的操作,注意其中宏指令#ifdef #else#endif的使用。这段代码可以在Win32、Linux和大多数Unix平台通过编译:#include ;#include ;#ifdef WIN32#define LOCALTIME_R(t) localtime(t)#define SNPRINTF _snprintf#else#define LOCALTIME_R(t) localtime_r(t), (struct tm *)&tmres)#define SNPRINTF snprintf#endifchar * getcurrentdate(char *buffer, unsigned int buflen) if (buffer) struct tm *tmnow; time_t long_time; time(&long_time ); /* Get time as long integer. */ tmNow = LOCALTIME_R( &long_time ); /* Convert to local time. */ SNPRINTF(buffer, buflen, %.4d-%.2d-%.2d %.2d:%.2d:%.2d, tmnow -;tm_year+1900, tmnow -;tm_mon + 1, tmnow -;tm_mday, tmnow -;tm_hour, tmnow -;tm_min, tmnow -;tm_sec); return buffer;研究一下上面的代码我们可以发现,由于一些库函数是非ANSI标准的,平台间有些差异,比如获得格式化字符串的函数在Win32平台叫_snprintf,而在Unix/Linux平台叫snprintf,它们之间的差别不是太大,通过使用编译宏指令就可以区分。1.2. 编译环境识别在C/C+编译器编译源码时,为了能够识别当前环境的状况,这包括编译器的类型和版本,操作系统的类型和版本,计算机CPU的类型,机器内部的字节顺序等,每种编译器内部一般规定了一些常用的宏定义,利用这些定义就可以区分出当前的编译环境了。如果我们开发的软件需要在很多不同的平台很编译器上编译,这时候环境就比较复杂了,这个时候如果我们能够将编译环境的宏定义转换成我们自己内部的约定,然后全部使用内部的约定来处理宏,这会简化我们进行跨平台移植的操作。举例来说,下面的一段代码可以区分目前多种常用的编译环境:#ifndef _ENV_MACROS_H_#define _ENV_MACROS_H_/* _ENV_I386 Intel i386/i486/Pentium (little endian)* _ENV_ALPHA Compaq/Digital Alpha (little endian)* _ENV_SPARC Sun Sparc* _ENV_HPPA HP PA-RISC* _ENV_MIPS MIPS* _ENV_PPC PowerPC* _ENV_POWER POWER Processors.* _ENV_MSVCPP Microsoft Visual C+ compiler; version* _ENV_WIN 32 or 64 bit Windows* _ENV_WINNT Windows NT* _ENV_WIN32 32 bit Windows* _ENV_WIN64 64 bit Windows* _ENV_UNIX UNIX* _ENV_SOLARIS SUN Solaris* _ENV_LINUX Linux* _ENV_HPUX HP UNIX* _ENV_AOSF Digital UNIX/Tru64 UNIX* _ENV_AIX IBM AIX* _ENV_IRIX SGI IRIX* _ENV_OS390 IBM OS/390* _ENV_AS400 IBM OS/400, AS/400* _ENV_MACOS Macintosh* _ENV_GNUC GNU C/C+ compiler; major version* _ENV_HP_ACC HP aC+ compiler; version* _ENV_SUNPRO Sun Pro/Workshop/Forte compiler; version (_ENV_SUNPRO_CC)* _ENV_SUNPRO_CC Sun Pro/Workshop/Forte CC compiler; version* _ENV_SUNPRO_C Sun Pro/Workshop/Forte C compiler; version* _ENV_SUN_SPARC Sun Sparc compilation mode* _ENV_SUN_SPARC32 Sun Sparc 32-bit compilation mode* _ENV_SUN_SPARC64 Sun Sparc 64-bit compilation mode* _ENV_SUN_I386 Sun i386 compilation mode* _ENV_AOSF_CC Compaq C+ compiler for Tru64; version* _ENV_INT64_NATIVE Compiler provides a 64-bit integer (not supported yet)* _ENV_64BIT_NATIVE defined for 64 bit platforms (not supported yet)* _ENV_CSET IBM AIX xlC, xlc, etc. this may be in old version.* _ENV_IBMC IBM AIX c compiler,xlc, cc.* _ENV_IBMCPP IBM AIX cpp compiler, xlC.* _ENV_MVSCPP IBM OS390 c+, cxx.* _ENV_MIPSPRO_CC SGI IRIX C* _ENV_BIG_ENDIAN_ARCH Defined if big-endian architecture* _ENV_LITTLE_ENDIAN_ARCH Defined if little-endian architecture* _ENV_SYSCALL _stdcall on Windows* _ENV_DECLSPEC_DLLEXPORT _declspec(dllexport) for VC+; empty otherwise* _ENV_DECLSPEC_DLLIMPORT _declspec(dllimport) for VC+; empty otherwise*/*/* Operating system / platform */*/* Windows platforms */#if (defined(WIN32) | defined(_WIN32) | defined(WIN64) | defined(_WIN64) | defined(_WIN32_)#define _ENV_WIN#if (defined(WIN32) | defined(_WIN32) | defined(_WIN32_)#define _ENV_WIN32#elif (defined(WIN64) | defined(_WIN64)#define _ENV_WIN64#endif#ifdef _WIN32_WINNT#define _ENV_WINNT#endif/* Alpha OSF / Tru64 / Digital UNIX */#elif (defined(_osf_)#define _ENV_AOSF#define _ENV_UNIX/* SUN Solaris - assumed */#elif (defined(_sun)#define _ENV_SOLARIS#define _ENV_UNIX/* IBM AIX */#elif (defined(_AIX)#define _ENV_AIX#define _ENV_UNIX /* AIX4.2 supports UNIX95, AIX4.3 supports UNIX98 */* SGI IRIX */#elif (defined(IRIX)#define _ENV_IRIX#define _ENV_UNIX/* IBM OS390 */#elif (defined(_MVS_)#define _ENV_OS390#define _ENV_UNIX /* OS/390 V2R2 UNIX95, OS/390 V2R7 UNIX98 */#elif (defined(EXM_OS390)#define _ENV_OS390#define _ENV_UNIX/* IBM AS400 */#elif (defined(_OS400_)#define _ENV_AS400#define _ENV_UNIX/* Macintosh */#elif (defined(macintosh)#define _ENV_MACOS/* Linux */#elif (defined(_linux_)#define _ENV_LINUX#define _ENV_UNIX/* HP Unix */#elif (defined(_hpux)#define _ENV_HPUX#define _ENV_UNIX/* Else */#else#warning Unknown platform!#endif/*/* Compiler */*/#if (defined(_MSC_VER) /* Microsoft Visual C+ */#define _ENV_MSVCPP _MSC_VER#elif defined(_BORLANDC_)#define _ENV_BORC /* Borland C/C+ */#elif defined(_WATCOMC_)#define _ENV_WATCOMC /* watcom c/c+ */#elif (defined(_GNUC_) /* GNU Project */#define _ENV_GNUC _GNUC_#elif (defined(_SUNPRO_CC) | defined(_SUNPRO_C) /* SUN Pro/Workshop/Forte */#define _ENV_SUNPRO _SUNPRO_CC#ifdef _SUNPRO_CC#define _ENV_SUNPRO_CC _SUNPRO_CC#endif#ifdef _SUNPRO_C#define _ENV_SUNPRO_C _SUNPRO_C#endif#elif (defined(_HP_aCC) /* HP aCC */#define _ENV_HP_ACC _HP_aCC#elif (defined(_xlC_) /* IBM C SET */#define _ENV_CSET _xlC_#elif (defined(_IBMC_) /* IBM c compiler */#define _ENV_IBMC _IBMC_#elif (defined(_IBMCPP_) /* IBM c+ compiler */#define _ENV_IBMCPP _IBMCPP_#elif (defined(_ENV_IRIX) | defined(_sgi)#define _ENV_MPISPRO_CC#elif (defined(_MVS_) & defined(_cplusplus) /* OS390 c+ compiler */#define _ENV_MVSCPP#elif (defined(EXM_OS390) & defined(_cplusplus) /* OS390 c+ compiler */#define _ENV_MVSCPP#elif (defined(_OS400_)#elif (defined(_DECCXX_VER) /* Compaq C+ */#define _ENV_AOSF_CC _DECCXX_VER#else#warning Unknown compiler!#endif/*/* Processor architecture */*/#if (defined(_ENV_MSVCPP)#ifdef _M_IX86 /* i386 architecture */#define _ENV_I386#endif#ifdef _M_ALPHA /* Alpha architecture */#define _ENV_ALPHA#endif#elif (defined(_ENV_SUNPRO)#ifdef _sparc /* Sparc architecture - 32-bit compilation mode */#define _ENV_SPARC#define _ENV_SUN_SPARC#define _ENV_SUN_SPARC32#endif#ifdef _sparcv9 /* Sparc architecture - 64-bit compilation mode */#define _ENV_SPARC#define _ENV_SUN_SPARC#define _ENV_SUN_SPARC64#endif#ifdef _i386 /* I386 architecture */#define _ENV_I386#define _ENV_SUN_I386#endif#elif (defined(_ENV_AOSF_CC)#ifdef _alpha /* Alpha architecture */#define _ENV_ALPHA#endif#elif (defined(_ENV_GNUC)#if (defined(_alpha) | defined(_alpha_)#define _ENV_ALPHA#elif (defined(_i386_)#define _ENV_I386#elif (defined(_sparc)#define _ENV_SUN_SPARC32#elif (defined(_hppa_)#define _ENV_HPPA#elif (defined(_mips_)#define _ENV_MIPS#elif (defined(_PPC_)#define _ENV_PPC#else#warning Unknown processor architecture!#endif#elif (defined(_ENV_HP_ACC)#if defined(_hppa)#define _ENV_HPPA#endif#elif (defined(_mips) | defined(_mips_) | defined(_MIPS_)#define _ENV_MIPS#elif (defined(_ENV_AIX)#if defined(_POWER)#define _ENV_POWER#endif#elif (defined(_ENV_MACOS)#define _ENV_PPC#elif (defined(_ENV_OS390)|defined(_ENV_AS400)#define _ENV_POWER#else#warning Unknown processor architecture!#endif/*/* Endian-ness */*/#if (defined(_ENV_I386) | defined(_ENV_ALPHA)#ifndef _ENV_LITTLE_ENDIAN_ARCH#define _ENV_LITTLE_ENDIAN_ARCH#endif /* _ENV_LITTLE_ENDIAN_ARCH */#ifdef _ENV_BIG_ENDIAN_ARCH#undef _ENV_BIG_ENDIAN_ARCH#endif /* _ENV_BIG_ENDIAN_ARCH */#else /* Sparc, etc. */#ifndef _ENV_BIG_ENDIAN_ARCH#define _ENV_BIG_ENDIAN_ARCH#endif /* _ENV_BIG_ENDIAN_ARCH */#ifdef _ENV_LITTLE_ENDIAN_ARCH#undef _ENV_LITTLE_ENDIAN_ARCH#endif /* _ENV_LITTLE_ENDIAN_ARCH */#endif /* Little-endian architectures */* TBD: How the hell do I detect endian-ness of HPPA machines, or is it transparent to the program? */*/* Miscellaneous macros */*/#if (defined(_ENV_MSVCPP)#define _ENV_DECLSPEC_DLLEXPORT _declspec(dllexport)#define _ENV_DECLSPEC_DLLIMPORT _declspec(dllimport)#define _ENV_SYSCALL _stdcall#define _ENV_DECLSPEC_DLLEXPORT_MID#elif defined(_ENV_OS390)#define _ENV_DECLSPEC_DLLEXPORT #define _ENV_DECLSPEC_DLLIMPORT #define _ENV_SYSCALL #define _ENV_DECLSPEC_DLLEXPORT_MID _Export#else /* not _ENV_MSVCPP */#define _ENV_DECLSPEC_DLLEXPORT#define _ENV_DECLSPEC_DLLIMPORT#define _ENV_SYSCALL#define _ENV_DECLSPEC_DLLEXPORT_MID#endif /* _ENV_MSVCPP */#endif /* _ENV_MACROS_H_ */以上的代码将原来编译器各自的环境宏转换成统一的以_ENV_开始的宏定义,可以区分当前编译器的类型、操作系统类型、系统内部字节顺序和计算机CPU类型等信息。有了这些信息,可以在移植代码和跨平台编码时方便地使用平台相关的特性。1.3. 定义通用的数据类型在目前的大多数计算机系统中,基本的数据类型在字节长度上基本一致,比如int类型占4个字节,char类型占1个字节等,但有些基本的数据类型还是有差别的,比如float、double和64位的整数类型,不同的平台还是有些差别的,为了方便进行跨平台的编程,定义一个通用的数据类型可以简化花费在数据类型上的时间。1.4. 利用平台交叉工具移植随着个人计算机性能的提高,目前比较先进的PC处理能力已经不比采用Unix操作系统平台的工作站差,苹果机(Mac)的速度也在成倍增长,最快Power Mac G5系列已经的采用了主频在2GHz以上的RISC 处理器。在这样的情况下,将原来在Unix平台上运行的软件下移到PC和Mac已经成为可能,这可以大大降低该软件的硬件平台的投资;同样,将PC或Mac上软件上移到Unix平台,可以充分发挥Unix平台的处理能力,更加有效地利用Unix平台,这同样也重要意义。在这样的背景下,有一些专业研究跨平台开发技术的公司和社会团体针对特定的应用推出了各种软件移植的解决方案,运用这些工具可以大大减少移植的代价。1.4.1. 从Unix/Linux到WindowsCygwin是Cygwin公司(/)的产品,它提供了Windows操作系统下的一个UNIX环境,它可以帮助程序开发人员把应用程序从UNIX/Linux移植到Windows平台,是一个功能强大的工具集。 Cygwin由仿真层和一组工具组成,cygwin1.dll:它作为UNIX的一个仿真层,提供UNIX API功能; Cygwin工具负责创建一个UNIX或Linux的外观界面。 Cygwin可以在Windows CE以外,Windows 95以上的所有非beta版本的Windows OS下工作,如Windows 98、Windows 2000、Windows XP等。 在Cygwin提供的仿真环境下,提供经过移植的Gcc编译器,很多原来在Unix/Linux上用Gcc编译的软件可以不加修改地在Windows下编译并运行,这极大地方便了软件从Unix到Window的移植,特别是一些开发原码的项目。NuTCRACKER是MKS公司(/)的产品,它为开发人员在Windows下提供了一个Unix的环境,用户可以方便地将Unix/Linux上使用X server、多线程程序移植到Windows平台下运行。img/forum/uploadfile/untitled_71551072874798.jpg/img MKS Toolkit企业开发版可以不仅可以开发、移植和部署非图形化的Unix应用程序和脚本程序,而且还可以移植原来使用X Windows, OpenGL。在安装好NuTCRACKER平台后,用户甚至可以直接使用Visual C+集成环境来编译来自Unix/Linux上的代码。直接将Unix上的代码拿到Windows下编译执行,这大大地节省了移植的成本。1.4.2. 从Windows到Unix/LinuxWind/U是bristol公司(/)开发的产品,它提供了一种将Win32程序顺利地移植到Unix和Linux操作系统方法。它在Unix和Linux系统上实现了Win32的API以及MFC框架,而且比较稳定。通过它提供的库和工具,可以十分方便地将Win32上使用API和MFC的软件移植到各种Unix和Linux系统中,大大节省移植的代价,由于它是一种商业产品,品质有保证,目前已经被很多公司采用。下图是Wind/U的系统结构:img/forum/uploadfile/untitled_34751072874963.jpg/img目前Wind/U已经可以很方便地支持从Win32到Solaris、HP-UX、AIX和RedHat Linux的移植。Visual MainWin 是 MainSoft(/)公司的产品,它也提供了从Win32程序代码直接生成Unix/Linux程序的方法。Visual MainWin 是一个企业级的移植和跨平台开发软件,它可以利用Visual C+集成环境来编写程序,然后将它们部署到多种的Unix平台中,并生成本地执行程序。它由两部分组成,Visual MainWin SDK和Visual MainWin 运行库, SDK是一个安装在Visual Studio中的跨平台插件,这个插件可以配合运行库来生成高可靠性的Unix平台代码。下图是Visual MainWin的使用框图:最新的Visual MainWin 5甚至可以移植.net框架和MFC7的应用程序到Unix平台。 2. 跨平台模块采用跨平台模块来组合开发跨平台软件,实际上是采用了组件的思想来进行跨平台软件的开发。这种方法目前正在被广泛采用,特别适用与具有跨平台需求的新产品开发中。在新的软件产品进行设计时就考虑到跨平台的需求,将软件按功能分成多个可组合的模块,定义好需求,然后由多个模块小组独立完成单个模块的,并完成在目标平台上的测试,同时的项目整合小组利用开发好的模块,组合成产品。由于各个模块都是跨平台设计的,所以整合时的跨平台问题会大大减少,这样可以在很短时间内推出一个产品的多个平台的运行版本。模块的思想非常有利于软件的复用,一般情况下,规模化经营的软件公司的产品大都形成系列化,各软件间的都有功能交叉的部分,采用模块化的思想,将这些部分独立出来,交由专门的小组负责维护和升级,让各产品组有更多的精力放在产品功能的更新上,有利于公司的整体效率的提高。如果一个公司的产品大多是跨平台的产品,那么组成专门的跨平台模块组是非常合适的。跨平台模块一般的要求也比较复杂,一般都要在三个典型的基准平台是Win32、Linux和Solaris。如果公司的产品还要支持Apple公司的平台,还的加上MacOS。由于平台的多样性,造成了跨平台模块开发

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论