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

来源:互联网 发布:购买软件付款方式 编辑:程序博客网 时间:2024/04/29 03:39
经过上述的几个步骤。第一个目标,代码能够编译通过基本上是不会有什么问题的。只要把握好二个修改代码的基本原则,第一。引入新的代码,而不修改原有的代码。在没有办法进行调试前修改源代码是不允许的,修改的不好就会引起最后代码运行逻辑的混乱,而且在代码能够运行之前是很难发现问题的。所以除非非常有把握,否则不要修改被移植工程的源代码。第二,引入新的代码之后,不能因为这次引入而需要再次引入新的代码。这样子,就进入死循环了。为了解决某个数据类型的定义,而引入了新的不能解释的数据类型。这样还不如不引入新的代码。所以引入新的代码,特别是很多头文件。引入之前一定要做修改,只保留工程本身需要的部分,去除那些不需要的代码。直到能编译通过为止。 三:第二个目标,使得代码能够链接过(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出来。放入工程中去。利用这些资料,并通过相关的工具比如sourceinsight来搜索Cygwin本身的源代码,Link问题并不难处理。只是有可能在处理link问题的过程中会回复到上面的问题,编译不过。这个时候的代码修改还是一定要注意不要引入太多的新的代码,免得问题越来越复杂。  四:代码运行正常  实际上当link问题解决之后,程序可以在windows环境中运行时,一切就尽在掌握了。如果不考虑做多平台的程序的话,这个时候就可以任意去修改程序了。不过在代码调试过程可能需要一个参照,看看正常的程序运行流程是怎么样的。刚刚移植过来的程序在很多地方并不能马上就能正常的运行。回到 Cygwin中,重新编译一个可以调试的版本(在GCC编译选项加上-g3),在需要的时候可以在Cygwin中调试程序。调试可以用GDB或者 Insight。如果习惯Windows 平台下面编程,可以使用Insight,这是一个TCL/TK脚本程序,它提供了一个Windows界面以方便用户调试程序,不过Insight最终还是调用GDB。在这里具体调试就不细说明了。  五:多平台代码  移植后的代码(本文于2003年完成. 如需要转载 请联系jackforce@163.com)如果需要在多个平台上面运行,就要在lib目录里面大做文章了。提供自己的函数库,并根据各个平台进行调整。Tar的代码由Config.h和一些编译选项来控制如何在各个不同的平台上面做编译。Lib则提供了很多C Library函数或者不同平台下面的其他函数的替代版本。这样Tar在编译过程中就不会因为某些平台下某些函数的缺失而编译不过。多平台支持,一般都是在代码中加上很多编译开关,在编译期间去分隔Linux,Windows或者其他平台下面的特殊代码。比如utime.h头文件的包含问题。因为文件在Linux(gcc)下面和Windows(cl)下所处的C Library目录不同。包含的处理办法就不一样。可能需要这样写才能完全正确的包含。#if HAVE_UTIME_H ---- 如果有utime.h 文件# ifdef WIN32 -----如果是win32环境 # include -----包含sys/utime.h# endif# ifdef LINUX ---- 如果是Linux环境# include ---- 包含utime.h # endif#else --- 如果没有utime.h定义出需要的结构 struct utimbuf{long actime;long modtime;};#endif   在其他的代码中基本上也是这样的处理。根据编译环境的不同来编译不同的代码。 这样的define的区隔,主要就是为了区隔不同平台的不同细微区别。有的区别也许是某些常量没有定义,有些区别是某些函数不存在。如果代码中调用函数在某些平台下面不存在,就需要提供一个lib去提供这些函数。Tar的 Lib的作用也是如此。  基本上代码的移植是前难后易。前期首先要保证源代码本身的逻辑不能变动,所以在修改代码方面只能尽量修改外围的代码,而不是修改源代码本身。如果link过了之后,则就是一般的Windows下面的编程了,可以根据需求任意修改移植后的代码了。最难的地方可能就是OS级不同概念的替换了。C Library虽然在各个平台上有不同之处,但是总是比较接近,不同的地方可以提供自己编写的代码来替换。但是OS级的概念,和平台相关性太大,一般不太容易替换。  六:扩展问题,待解决的问题  如果需要把移植过来的代码改成DLL或者lib给其他的工程调用。比如给其他的工程提供一个解包Tar文件的功能。如果不加修改,那么移植过来的代码有很多缺陷。  首先是多线程支持问题。如果代码中有很多全局变量,那么改成DLL或者lib之后就不能在多线程下面调用。  其次,DLL接口表。移植后的代码入口是main函数,虽然整个工程里面有很多独立功能,但是这些独立功能的调用都是通过使用不同的参数来实现。如何输出接口表给其他工程使用,需要做些功夫。  三、控制 原始的控制台程序在下了运行参数之后,一般都是一头运行到底的,也有可能在中间有些要求输入某些信息的。这样的程序如何集成到其他的工程中并受到其他工程的控制?比如遇到某些错误要返回等等。在Tar代码中遇到错误就直接退出程序。显然这些地方就不合DLL设计要求。可能需要重新设计代码的结构。  四,输出信息。Tar工程里面很多向控制台输出的信息。这些信息输出需要重新定向或者屏蔽。  第三第四部分可以参考Linux下面的FrontEnd程序,即只是为某个特殊的程序提供的一个GUI界面的程序。FrontEnd程序就是控制了主程序的运行并重新定向输出信息到GUI界面上。  注1. Cygwin,是Windows平台下面的一个Linux模拟环境。可以从www.Cygwin.com上下载全部内容。  注2. Windows Services for UNIX (SFU)的SDK可以从微软网站上获得 http://www.microsoft.com/windows/sfu/ ;  注3. UNIX Application Migration Guide 可以从MSDN中取得,如果没有MSDN可以从微软MSDN网站上取得。 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnucmg/html/ucmglp.asp ;  注4. Tar, Cygwin下面有Tar。但是只能在Cygwin下面运行 或者必须提供Cygwin的平台DLL才能在windows下面单独使用Tar程序。注5. CL是微软的C/C++编译器,包含在Visual Studio各个版本中  本文于2003年完成. 如需要转载 请联系jackforce@163.com,如果有看到部分干扰信息.请原谅.主要避免转载过程中作者信息丢失用.不得以为之,请各位原谅.
原创粉丝点击