Windows向Linux代码移植常见问题

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

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

例如

[plain]  view plain  copy
  1. decode_test_utils.cpp:1:20: fatal error: StdAfx.h: No such file or directory  
  2.  #include "StdAfx.h"  

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

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

例如,

[plain]  view plain  copy
  1. targetver.h:8:23: fatal error: SDKDDKVer.h: No such file or directory  
  2.  #include <SDKDDKVer.h>  

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

再举另一个例子:

[plain]  view plain  copy
  1. decode_test_utils.cpp:288:2: error: ‘BITMAPFILEHEADER’ was not declared in this scope  
  2.   BITMAPFILEHEADER bmpheader;    
  3.   ^  
  4. decode_test_utils.cpp:288:19: error: expected ‘;’ before ‘bmpheader’  
  5.   BITMAPFILEHEADER bmpheader;    
  6.                    ^  
  7. decode_test_utils.cpp:289:2: error: ‘BITMAPINFOHEADER’ was not declared in this scope  
  8.   BITMAPINFOHEADER bmpinfo;    
  9.   ^  
  10. decode_test_utils.cpp:289:19: error: expected ‘;’ before ‘bmpinfo’  
  11.   BITMAPINFOHEADER bmpinfo;    
  12.                    ^  
  13. decode_test_utils.cpp:290:10: error: ‘bmpheader’ was not declared in this scope  
  14.   memset(&bmpheader, 0, sizeof(BITMAPFILEHEADER));    
  15.           ^  
  16. decode_test_utils.cpp:291:10: error: ‘bmpinfo’ was not declared in this scope  
  17.   memset(&bmpinfo, 0, sizeof(BITMAPINFOHEADER));    
  18.           ^  
  19. decode_test_utils.cpp:312:26: error: ‘BI_RGB’ was not declared in this scope  
  20.   bmpinfo.biCompression = BI_RGB;    

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

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

例如,

[plain]  view plain  copy
  1. decode_test_utils.cpp:125:24: error: ‘_access’ was not declared in this scope  
  2.  if(_access(sub_path, 0) < 0)  

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

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

[plain]  view plain  copy
  1. decode_test_utils.cpp:136:30: error: too few arguments to function ‘int mkdir(const char*, __mode_t)’  
  2.    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()会报错

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

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

5. 链接错误

(1) 

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

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

(2) 

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

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

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

猜你喜欢

转载自blog.csdn.net/weixin_41940752/article/details/80799478
今日推荐