今天花了整一天的时间... 来说说心得:
1. 首先翻了下vc和gcc的一些preprocessor definition, 然后分别用"_WIN32", "__linux__"来区分编译.
参考:
vc: http://msdn.microsoft.com/en-us/library/b0084kay.aspx
gcc: http://gcc.gnu.org/onlinedocs/cpp/Predefined-Macros.html
有1个命令很实用, 可以用来看gcc的preprocessor definition:
linux% cpp -dM [-undef] /dev/null
2. 把win32的一些macro替换掉, 比如:
BOOL --> bool.
UINT --> unsigned int.
3. 把一些win32的一些api替换掉或者不用, 比如:
ZeroMemory() --> memset().
CopyMemory() --> memcpy().
4. 还有一些似乎linux下不通用, 我这么改的, 全部弄成macro:
#ifdef _WIN32
#define hs_stricmp stricmp
#define hs_sleep(seconds) Sleep((seconds*1000))
#endif
#ifdef __linux__
#include <strings.h>
#define hs_stricmp strcasecmp
#define hs_sleep(seconds) sleep((seconds))
#endif
5. 然后就是替换一些linux下没有的api了, 这个最麻烦, 我的方法是调用3rdparty的library, 比如pthread库.
6. 因为项目涉及到socket编程, 还好win32和linux下的socket的api还差不太多, 但是还是有区别的:
a) win32下把一个socket的descriptor定义成SOCKET宏, 其实就是一个unsiged int, 而linux下就是一个int的值, 所以我直接统统用了int.
b) win32下关一个socket用的函数是closesocket(), 而linux下用的则是close(), 这个也用一个macro搞定吧.
c) 有一个函数setsockopt()很诡异. 我要设一个timout的值, win32下第4个参数传的是char 的指针:
setsockopt(sktRemote, SOL_SOCKET, SO_RCVTIMEO, (char *)&iOptval, (socklen_t)sizeof(int));
而linux下第4个参数一定要传struct timeval 这个结构的指针, 不然直接报错:
setsockopt(sktRemote, SOL_SOCKET, SO_RCVTIMEO, (struct timeval *)&tv, (socklen_t)sizeof(struct timeval));
然而, 用#ifdef流肯定是能解决问题的, 但是太麻烦了, 就么一个函数. 经过实践, 我发现, 可以这么传:
setsockopt(sktRemote, SOL_SOCKET, SO_RCVTIMEO, (char *)(struct timeval *)&tv, (socklen_t)sizeof(struct timeval));
就是先转成struct timeval 的指针再转成char 的指针, 呵呵.
7. 写一个Makefile吧, 不用automake了, 手写, 毕竟文件不多. 一边编译一边改, 终于全部编译过了. 然而link的时候出问题了:
undefined reference to 'operator new[](unsigned int)'
囧.. new也会找不到么... google了一下说link的时候要指定link到std库: -lstdc++.
8. 其实之前一直都是用cygwin编译的, 很容易就过了编译, 而到了linux下依然好多的错, 为什么呢? 原来cygwin下提供了一套win32 api, 所以..... 代码几乎都不用改的..... 诶.. cygwin这个东西果然很高级. 后来通过在Makefile里加一个-D__linux__保证不引用win32 api.
以上.



