C++的可移植性和跨平台开发[5]:操作系统

上一个帖子提到了"硬件体系"相关的话题,今天来说说和操作系统相关的话题 。C++跨平台开发中和OS相关的琐事挺多,所以今天会啰嗦比较长的篇幅,请列位看官见谅 :-)

为了不绕口,以下把Linux和各种Unix统称为Posix系统。

★文件系统(FileSystem以下简称FS)

刚开始搞跨平台开发的新手,多半都会碰上和FS相关的问题。所以先来聊一下FS。归纳下 来,开发中容易碰上的FS差异主要有如下几个:目录分隔符的差异;大小写敏感的差异;路 径中禁用字符的差异。

为了应对上述差异,你要注意如下几点:

1、文件和目录命名要规范

在给文件和目录命名时,尽量只使用字母和数字。不要在同一个目录下放两个名称相似( 名称中只有大小写不同,例如foo.cpp与Foo.cpp)的文件。不要使用某些OS的保留字(例如 aux、con、nul、prn)作文件名或目录名。

补充一下,刚才说的命名,包括了源代码文件、二进制文件和运行时创建的其它文件。

2、#include语句要规范

当你写#include语句时,要注意使用正斜线"/"(比较通用)而不要使用反斜 线"\"(仅在Windows可用)。#include语句中的文件和目录名要和实际名称保持 大小写完全一致。

3、代码中涉及FS操作,尽量使用现成的库

已经有很多成熟的、用于FS的第三方库(比如boost::filesystem)。如果你的代码涉及 到FS的操作(比如目录遍历),尽量使用这些第三方库,可以帮你省不少事情。

★文本文件的回车CR/换行LF

由于几个知名的操作系统对回车/换行的处理不一致,导致了这个烦人的问题。目前的局 面是:Windows同时使用CR和LF;Linux和大部分的Unix使用LF;苹果的Mac系列使用CR。

对于源代码管理,好在很多版本管理软件(比如CVS、SVN)都会智能地处理这个问题,让 你从代码库取回本地的源码能适应本地的格式。

如果你的程序需要在运行时处理文本文件,要留意本文方式打开和二进制方式打开的区别 。另外,如果涉及跨不同系统传输文本文件,要考虑进行适当的处理。

★文件搜索路径(包括搜索可执行文件和动态库)

在Windows下,如果要执行文件或者加载动态库,一般会搜索当前目录;而Posix系统则不 尽然。所以如果你的应用涉及到启动进程或加载动态库,就要小心这个差异。

★环境变量

对于上述提到的搜索路径问题,有些同学想通过修改PATH和LD_LIBRARY_PATH来引入当前 路径。假如使用这种方法,建议你只修改进程级的环境变量,不要修改系统级的环境变量( 修改系统级有可能影响到同机的其它软件,产生副作用)。

★动态库

如果你的应用程序使用动态库,强烈建议动态库导出标准C风格的函数(尽量不要导出类 )。如果在Posix系统中加载动态库,切记慎用RTLD_GLOBAL标志位。这个标志位会Enable全 局符号表,有可能会导致多个动态库之间的符号名冲突(一旦碰到这种事,会出现匪夷所思 的运行时错误,极难调试)。

关于动态库的话题比较大,限于篇幅,以后单独写一个帖子讨论。

★服务/看守进程

如果你不清楚服务和看守进程的概念,请看维基百科(这里和这里)。为了叙述方便,以 下统称服务。

由于C++开发的模块大部分是后台模块,经常会碰到服务的问题。编写服务需要调用好几 个系统相关的API,导致了与操作系统的紧密耦合,很难用一套代码搞定。因此比较好的办法 是抽象出一个通用的服务外壳,然后把业务逻辑代码作为动态库挂载到它下面。这样的话, 至少保证了业务逻辑的代码只需要一套;服务外壳的代码虽然需要两套(一个用于Windows、 一个用于Posix),但他们是业务无关的,可以很方便地重用。

★默认栈大小

不同的操作系统,栈的默认大小差别很大,从几十KB(据说Symbian只有12K,真抠门)到 几MB不等。因此你事先要打听一下目标系统的默认栈大小,如果碰上像Symbian这样抠门的, 可以考虑用编译器选项调大。当然,养成"不在栈上定义大数组/大对象"的好习惯 也很重要,否则再大的栈也会被撑爆的。

时间: 2024-07-28 13:07:17

C++的可移植性和跨平台开发[5]:操作系统的相关文章

C++的可移植性和跨平台开发[1]:编译器

在跨平台的开发过程中,很多问题都和编译器有关.因此我们先来聊聊编译器相关的问题 . ★编译器的选择 首先,GCC是优先要考虑支持的,因为几乎所有操作系统平台都有GCC可用.它基本上成了 一个通用的编译器了.如果你的代码在A平台的GCC能够编译通过,之后拿到B平台用类似版本 的GCC编译,一般也不会有太大问题.因此GCC是肯定要考虑支持的. 其次,要考虑是否支持本地编译器.所谓本地编译器就是操作系统厂商自产的编译器.例 如相对于Windows的本地编译器就是Visual C++.相对于Solari

C++的可移植性和跨平台开发[4]:硬件体系相关

这次聊的话题主要是和硬件体系有关的.比如你的程序需要支持不同类型的CPU(x86.SPARC.PowerPC),或者是同种类型不同字长的CPU(比如x86和x86-64),这时候你就需要关心一下硬件体系的问题. ★基本类型的大小 C++中基本类型的大小(占用的字节数)会随着CPU字长的变化而变化.所以,假如你要表示一个int占用的字节数,千万不要直接写"4"(顺便说一下,直接写"4"还犯了Magic Number的大忌,详见这里),而应该写"sizeof(

C++的可移植性和跨平台开发[3]:异常处理

上一个帖子"语法"由于篇幅有限,没来得及聊异常,现在把和异常相关的部 分单独拿出来说一下. ★小心new分配内存失败 早期的老式编译器生成的代码,如果new失败会返回空指针.我当年用的Borland C++ 3.1 似乎就是这样的,现在这种编译器应该不多见了.如果你目前用的编译器还有这种行为,那 你就惨了.你可以考虑重载new操作符来抛出bad_alloc异常,便于进行异常处理. 稍微新式一点的编译器,就不是仅仅返回空指针了.当new操作符发现内存告急,按照标 准的规定(参见03标准1

C++的可移植性和跨平台开发[2]:语法

目前还有相当一部分开发人员在使用老式编译器干活,这些老式编译器可能对C++98支持 不够.因此,当你的代码移植到这些老式的编译器上时,可能会碰到一些稀奇古怪的问题( 包括编译出错和运行时错误).下面这些注意事项有助于你绕过这些问题. 强调一下 ,后面提到的好几个条款都是通过回避C++的新语法来保证移植性.如果你用的是新式编译器 ,那么你可以不理会这些条款. ★小心for循环变量的作用域(不支持新标准) 在C++98标准中,for循环变量的作用域局限在循环体内.而某些老的编译器(例如 Visual

为什么移动端跨平台开发不靠谱?

本文讲的是为什么移动端跨平台开发不靠谱?, 前言 翻墙偶然读到一篇不错的文章,随手翻译,作者是jielse发表于androidHub. 台风过后的城市 随着智能手机的发明,许多开发人员都提出了同样的问题:如何为多个移动平台构建和发布应用程序? 包括最初的iPhone和BlackBerries,Android,以及Windows Phone和Web. 每个平台单独发布应用程序是很昂贵的.我们最初的想法: 肯定有一个解决方案可以降低开发多个应用的成本.但是事实是不是这样的呢? 在Pixplicity

DT科技评论第39期:谷歌正秘密开发Fuchsia操作系统

DT科技评论 Data Technology Review 第 39 期           阿里云研究中心,人民网研究院,DeepTech深科技 本期目录 谷歌正秘密开发Fuchsia操作系统 微软Build 2017开发者大会 PowerVR GT8525新架构GPU发布 亚马逊推出触屏智能音箱Echo Show Facebook研发AI翻译技术 谷歌移动页面更新支持直接搜索周边展览活动 微软获得存储系统侵权内容识别专利 AWS发布美国国防部云计算合规规范白皮书 云安全创业公司RedLock

新手学Linux(二)----使用 Vagrant 打造跨平台开发环境(一)

前言 什么是Vagrant Vagrant能做什么 尽可能避免Work on my machine错误 缩短搭建开发环境的时间 Vagrant的主要使用者 前言     做Web开发少不了要在本地搭建好开发环境,虽然说目前各种脚本都有对应的Windows版,甚至是一键安装包,但很多时候和Windows环境的相性并不是那么好,各麻烦的问题是实际部署的环境通常是Linux,常常还要面临着开发和部署环境不一致,上线前还要大量的调试.更要命的是,如果有很多机器需要装的话,那就真是一个灾难了. 什么是Va

【Xamarin开发 Android 系列 2】VS2015跨平台开发的几种方式

原文:[Xamarin开发 Android 系列 2]VS2015跨平台开发的几种方式   在微软Build大会上,微软宣布在VS2015中支持三种方式进行跨平台的开发. 1. Xamarin 2. Cordova 3. C++ Xamarin  官网 :http://xamarin.com/ Xamarin 是由早期的Mono项目演变而来,原本是在Linux上执行C#程序的一个开放原始码项目.后来陆续发表支持iOS的Mono Touch framework以及Mono For Android

arcgis-Qt 结合ArcGIS for Qt SDK跨平台开发

问题描述 Qt 结合ArcGIS for Qt SDK跨平台开发 刚接触Qt,ESRI针对Qt推出的SDK也不太了解,二者结合进行跨平台开发,现在连helloword都编译失败,求大神指点. 解决方案 sdk正确安装了么?安装好了能直接创建地图的工程啊