博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

对于C语言可移植性的思考【转】【补充】

Posted on 2011-03-27 17:02  天地玄黄  阅读(1162)  评论(0编辑  收藏  举报

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://vanshell.blog.51cto.com/890307/417068

      我相信学过C语言的同学,都会在书中看到C语言特点一定有:可移植性。但是什么是可移植?如何才能可移植?C语言是如何做到可移植的?对于初学者,可移植可能是一个经常遇到却很神秘的词。我想通过这篇文章来表达我对于可移植性的一些想法。

    首先,在这里铺垫一下。学过Win32程序设计的人肯定都听说过API(Application Program Interface)。我就先说说API,高手绕过。API对于程序员来说就是系统提供的接口,任何涉及系统调用都要通过API来完成。对于不同的操作系统都有不同的一套API,也就是说对于不同的操作系统系统调用的接口是完全不同的。所以在API层我们是不能移植的。

下面我就来说说可移植,可移植顾名思义就是可以从一个平台移植到另外一个平台,但是大家一定要清楚,移植是基于操作系统的。但是这个时候,我们需要注意一点:基于各种操作系统平台不同,应用程序在二级制级别是不能直接移植的。我们只能在代码层去思考可移植问题,在API层面上由于各个操作系统的命名规范、系统调用等自身原因,在API层面上实现可移植也是不大可能的。那怎么才能实现可移植呢?

我们首先来看看现在主流的Windows和Linux平台下代码可移植性。有什么办法解决这个问题呢?答案是:在各个平台之间,基于大部分需求抽象出一个中间层。在中间层中,中间层用了屏蔽底层细节,在我们程序员看来C言语库就是这样一个中间层的作用。在各个平台下,我们默认C标准库中的函数都是一样的,这样基本可以实现可移植。但是对于C库本身而言,在各种操作系统平台下其内部实现是完全不同的,也就是说C库封装了操作系统API在其内部的实现细节。

因此,C语言提供了我们在代码级的可移植性,即这种可移植是通过C语言这个中间层来完成的。

当然,大家都可以看出上面的可移植是有条件的,C语言本身不能实现完全的可移植,为什么呢?因为,在我们程序中,我们经常会调用系统API,由于这些API在C语言中没有对其封装,所以我们只能用使用其原始的API,对于原始的API在各个操作系统中他们命名不同,就不能跨平台移植。所以,我们要写出完完全全的跨平台的程序,还是需要其他的一些手段。例如在我们的代码中下功夫。以下代码可以帮助我们实现各平台之间的可移植:

#ifndef _WINDOWS_

       CreateThread();      //windows下线程的创建

#else

       Pthread_create();    //Linux下线程的创建

#endif

对于头文件,也使用同样的预编译宏来实现。如:

#ifndef _WINDOWS_

       #include <windows.h>

#else

       #include <thread.h>

#endif

这样就可以实现代码的可移植了。在编译的时候只要通过#define就可以选择在那个平台下完成程序的编译。

综上所述,我们都是将C,C++等各种语言当作中间层,以实现其一定程度上的可移植。如今,语言的跨平台的程序都是以这样的方式实现的。但是在不同的平台下,仍需要重新编译。

本文出自 “HelloWorld” 博客,请务必保留此出处http://vanshell.blog.51cto.com/890307/417068

 

 

谢谢作者的博文,我自己也有一些理解:

我是从汇编语言中想到这个问题的。在Linux的汇编中,Assembler使用的是NASM,它没有提供自己的库函数,都是直接调用Linux的系统函数。比如要在Console中显示一行字,那么就要进行int 80h的系统调用,通过Linux System Call Dispatcher来调用具体的函数执行这个动作。而这样一个动作,在C语言中只需要调用printf()这个函数即可。这一个函数在Linux中这样写,在Windows中也是这样写。由此想到这是否说明C语言是这样具有可移植性的。

 

又想到在Linux和Windows中,C语言代码最后编译完成之后的可执行代码不能互相交换平台运行,所以C语言的可移植性不应该是在二进制可执行代码级别的。那么就可能是Code级别(也就是源代码级别)。同样的代码,在Linux下用Linux中的C编译器(gcc)编译一下,就可以在Linux平台下运行;在Windows下用Windows中的编译器(Visual Studio 2005)编译一下,就可以在Windows平台下运行。那么,C语言的编译器就充当了一个中间人的角色,屏蔽了底层的差异。

 

不过我还不理解C语言编译器究竟是什么东西?它里面有什么东西?

为什么会有C语言函数库?

所有的C语言函数库都是标准的吗?

C语言函数库是怎么实现的?是.o文件吗?.o文件是什么样的文件?用汇编吗?