将Linux代码移植到Windows的简单方法( 三 )


除了修改外围的各种头文件之外,还不要忘了修改工程的编译选项,特别是预定义选项 。在Tar的移植过程就需要以下的预定义HAVE_CONFIG_H,_POSIX_SOURCE,MSDOS 。HAVE_CONFIG_H 表示程序编译需要config.h文件 。为了方便期间,在tar移植过程中就放到工程的预编译选项中了 。MSDOS,移植的是Linux下的控制台程序,而Windows平台最接近Linux控制台就是DOS,特别是一些环境变量设置和全局常量的定义 。Tar的有些代码针对MSDOS环境已经做了一部分修正,这点在移植过程中可以利用起来 。还有一个可选项是__CYGWIN__ 。有些Linux程序会针对Cygwin平台做出代码上的特殊设定 。当遇到这样的代码的时候,一定要加上__CYGWIN__预定义项,能够大大减少移植需要的工作量 。还有就是移植过程引入的各种Cygwin代码中也可能需要__CYGWIN__定义(有时候是其他的定义,比如_POSIX_SOURCE,或者__INSIDE_CYGWIN__) 。
经过上述的几个步骤 。第一个目标,代码能够编译通过基本上是不会有什么问题的 。只要把握好二个修改代码的基本原则,第一 。引入新的代码,而不修改原有的代码 。在没有办法进行调试前修改源代码是不允许的,修改的不好就会引起最后代码运行逻辑的混乱,而且在代码能够运行之前是很难发现问题的 。所以除非非常有把握,否则不要修改被移植工程的源代码 。第二,引入新的代码之后,不能因为这次引入而需要再次引入新的代码 。这样子,就进入死循环了 。为了解决某个数据类型的定义,而引入了新的不能解释的数据类型 。这样还不如不引入新的代码 。所以引入新的代码,特别是很多头文件 。引入之前一定要做修改,只保留工程本身需要的部分,去除那些不需要的代码 。直到能编译通过为止 。三:第二个目标,使得代码能够链接过(Link)
完成了第一个目标之后,就会有大量的link错误 。原因是前面引入了很多外部函数,外部全局常量只有定义而没有实体,于是就会产生link错误 。现在需要的是为代码提供引入的函数实体,外部全局变量实体 。一般都是函数link(本文于2003年完成. 如需要转载 请联系jackforce at 163.com)不到的比较多 。
要解决link错误就需要了解不同平台上面函数操作的区别,特别是某些概念的区别 。这里最好的参考资料有两个 。一个是Windows Services for UNIX (SFU)的帮助文件,一个是MSDN中的一篇文章《UNIX Application Migration Guide》 。SFU是微软提供一个Unix兼容环境,有点像Cygwin 。在安装上SFU之后有一个帮助文件 。其中有一部分就是Unix,Linux函数的说明,有些函数提供了信息说明可以用Windows Library中那些函数来替代 。这点对于移植是很重要的(省事) 。UNIX Application Migration Guide应该不算文章而是有点像书了 。它说明了很多windows和Unix系统(类Unix系统)中很多概念不同之处,针对这些不同的概念提供了很多相关的信息来说明如何进行模拟这些不同之处 。比如Unix系统中Signals概念可以使用Windows环境中的Event来替代 。SIGALRM用Windows Message来替代等 。
SFU的帮助文件提供了一部分信息来说明Windows平台中哪些低阶函数(C 函数库)可以替代相关Unix函数 。《UNIX Application Migration Guide》则提供了一种方法来转换Unix平台上的一些OS级的概念到windows上 。实际上Cygwin下面也做了很多这样的转换 。具体解决link问题的时候可以参考Cygwin本身的实现 。
不过有些概念,比如安全权限方面的概念 。在Linux平台和windows平台上面是完全不能互换的 。而且windows平台中的权限函数操作(本文于2003年完成. 如需要转载 请联系jackforce@163.com)的过于复杂 。这样对于某些linux函数 。比如getuid处理可以参考Cygwin的处理办法 。什么也不做直接返回0 (return 0) 。当代码中遇到这些函数的时候可以从Cygwin的代码中复制一个getuid出来 。放入工程中去 。

推荐阅读