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


利用这些资料,并通过相关的工具比如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函数,虽然整个工程里面有很多独立功能,但是这些独立功能的调用都是通过使用不同的参数来实现 。如何输出接口表给其他工程使用,需要做些功夫 。

推荐阅读