记一次Windows向Linux的代码移植

前几天完成了一次Windows向Linux的代码移植,由于在Windows上开发时没有考虑到兼容性,所以移植的时候还是碰到了不少的问题,今天专门抽时间把问题和解决方法整理出来,作为经验,以备将来查阅。

1. 包含的头文件名称大小写问题

例如

decode_test_utils.cpp:1:20: fatal error: StdAfx.h: No such file or directory
 #include "StdAfx.h"

Windows下VS编译器对文件名称的大小写不敏感,但在Linux下使用gcc或g++编译器则会报错,这种错误解决方法很简单,把#include包含的头文件名称改为与实际名称字母大小写一致即可。

2. Windows下的头文件在Linux下不存在

例如,

targetver.h:8:23: fatal error: SDKDDKVer.h: No such file or directory
 #include <SDKDDKVer.h>

这里的SDKDDKVer.h是支持一些Windows API的调用的,在VS生成的targetver.h中包含,在Linux下面基本用不到这些。因此,可加入系统判断,只在Windows下才包含该头文件。

再举另一个例子:

decode_test_utils.cpp:288:2: error: ‘BITMAPFILEHEADER’ was not declared in this scope
  BITMAPFILEHEADER bmpheader;  
  ^
decode_test_utils.cpp:288:19: error: expected ‘;’ before ‘bmpheader’
  BITMAPFILEHEADER bmpheader;  
                   ^
decode_test_utils.cpp:289:2: error: ‘BITMAPINFOHEADER’ was not declared in this scope
  BITMAPINFOHEADER bmpinfo;  
  ^
decode_test_utils.cpp:289:19: error: expected ‘;’ before ‘bmpinfo’
  BITMAPINFOHEADER bmpinfo;  
                   ^
decode_test_utils.cpp:290:10: error: ‘bmpheader’ was not declared in this scope
  memset(&bmpheader, 0, sizeof(BITMAPFILEHEADER));  
          ^
decode_test_utils.cpp:291:10: error: ‘bmpinfo’ was not declared in this scope
  memset(&bmpinfo, 0, sizeof(BITMAPINFOHEADER));  
          ^
decode_test_utils.cpp:312:26: error: ‘BI_RGB’ was not declared in this scope
  bmpinfo.biCompression = BI_RGB;  

BITMAPFILEHEADER、BITMAPINFOHEADER等定义在Windows系统下的WinGDI.h里面,在Linux下则没有该头文件。我的解决方法是,将程序中用到的结构体、宏定义从WindGDI中拷贝出来,放在自己新建的头文件mytypedef.h里面,并将自建的头文件包含在代码中。

3.  Linux下同一功能函数的名称、参数与Windows不一致

例如,

 decode_test_utils.cpp:125:24: error: ‘_access’ was not declared in this scope
  if(_access(sub_path, 0) < 0)

解决方法是,加入对系统的判断,win32下调用_access和_mkdir,Linux下调用access 和mkdir。 相似错误还有_stat。

除了函数名称不一致,有可能函数传入的参数也不一致,例如mkdir:

decode_test_utils.cpp:136:30: error: too few arguments to function ‘int mkdir(const char*, __mode_t)’
   mkdir((const char*)sub_path);

在Windows下,_mkdir形式为:int _mkdir( const char *dirname ),而在Linux下,mkdir不光要传入需要创建的路径,而且要传入新建路径的权限,形式为int mkdir(const char *pathname, mode_t mode),mode可以是多个权限的组合,例如如下语句是为新建的路径赋予所有人读、写、可执行权限。

mkdir(sub_path,S_IRWXU | S_IRWXG | S_IRWXO); 

4. Linux编译void main()会报错

online_test.cpp:305:33: error: ‘::main’ must return ‘int’
 void main(int argc, char *argv[])

在Windows VS下,编译void main()可以通过,但在Linux下面则不支持void类型的main函数,必须要返回int值。

5. 链接错误

(1) 

/usr/bin/ld: /tmp/ccH3cL83.o: undefined reference to symbol 'pthread_mutexattr_settype@@GLIBC_2.2.5'
/usr/lib64/libpthread.so.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status

解决方法:在Makefile中编译选项中加入 -lpthread。

(2) 

/usr/bin/ld: /tmp/ccWPCTf3.o: undefined reference to symbol 'floor@@GLIBC_2.2.5'
/usr/lib64/libm.so.6: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status

解决方法:在编译选项中加入-lm。

暂时记录了以上的几个问题,实际在移植过程中,由于最开始Makefile写的不好,也出现了不少编译错误,后来完善了Makefile后,一些不必要的错误才消失。后面准备写一篇如何编写Makefile的文章。

猜你喜欢

转载自blog.csdn.net/DeliaPu/article/details/79678007