Windows c 和 Linux c 的区别
c 语言本身的区别不大,主要是和系统交互的时候会有差异。
- Linux 下是 POSIX 接口,Windows 下是 Win32 API
平台环境
Linux
centos:centos 6.5
编译工具:gcc
Windows
Windows 10
编译工具:vs 2005
Debug:x64
移植开始
1. 创建 vs 工程
- 将源代码添加到工程里面
- 调试编译代码
2. 解决报错信息
1. 解决头文件报错
- unistd.h
- dirent.h
- pthread.h
2. 声明
- 在 Linux 上变量声明可以放在任意位置
- Winodws 上的声明必须放在可执行代码之前
3. 换行符
- Windows 上的换行符需要改成 CRLF
- Linux 上的换行符支持 LF 和 CRLF
4. getpid
- Linux 上引入 unistd.h
- Windows 上引入 process.h
5. 可变参数
#ifdef _WIN32#define ARG(fmt, ...) test_arg(fmt, __VA_ARGS__)#else#define ARG(fmt, args...) test_arg(fmt, ##args)#endif
6. getopt
参考连接:https://www.jianshu.com/p/991e554d4861
7. dirname
Windows 上没有 dirname 的函数,所以就只有靠自己写一个
#ifdef _WIN32char drive[_MAX_DRIVE]; //路径中的盘符,例如"d:"char dir[_MAX_DIR]; //文件夹,例如"\sample\crt\"char fname[_MAX_FNAME]; //文件名称,例如"crt_makepath_s"char ext[_MAX_EXT]; //文件扩展名,例如".c"errno_t err;err = _splitpath_s(full_path, drive, _MAX_DRIVE, dir, _MAX_DIR, fname,_MAX_FNAME, ext, _MAX_EXT); //拆分路径if (err != 0){printf("Error splitting the path. Error code %d.\n", err);exit(1);}sprintf(full_path, "%s%s", drive, dir); //文件夹全路径,例如"d:\sample\crt\"#elsedirname(full_path);#endif
8. openssl
参考链接:https://blog.csdn.net/liudongdong19/article/details/84255554
9. sleep
windows 下是 Sleep,Linux 下是 sleep
#ifdef _WIN32Sleep(ms)#elsesleep(s)#endif
10. socket
在连接 socket 的时候有区别
#ifdef _WIN32// Windows下连接服务器WSADATA wsaData;int timeout = conn_timeout * 1000;if (client_conn->data_fd != INVALID_SOCKET) {// log_write(LOG_WARN, "the data_fd is not zero, may be initialised");printf("the data_fd is not zero, may be initialised\n");}if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){printf("WSAStartup failed");SET_ERRNO(client_conn->error);goto out;}client_conn->data_fd = socket(AF_INET, SOCK_STREAM, 0);if (client_conn->data_fd == INVALID_SOCKET){printf("create socket failed");SET_ERRNO(client_conn->error);goto out;}memset(&(client_conn->peer_sockaddr), 0, sizeof(client_conn->peer_sockaddr));client_conn->peer_sockaddr.sin_family = AF_INET;client_conn->peer_sockaddr.sin_port = htons(client_conn->peer_port);client_conn->peer_sockaddr.sin_addr.s_addr = inet_addr(client_conn->peer_ipaddr);if (connect(client_conn->data_fd, (struct sockaddr*)&(client_conn->peer_sockaddr), sizeof(struct sockaddr)) == -1){printf("client failed to connect server, errorno: %d", errno);closesocket(client_conn->data_fd);}setsockopt(client_conn->data_fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(int));setsockopt(client_conn->data_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(int));#elsestruct timeval timeout = {conn_timeout, 0};if (client_conn->data_fd != 0) {log_write(LOG_WARN, "the data_fd is not zero, may be initialised");}client_conn->data_fd = socket(AF_INET, SOCK_STREAM, 0);if (client_conn->data_fd == -1) {log_write(LOG_ERROR, "client failed to create socket, errno: %d", errno);SET_ERRNO(client_conn->error);client_conn->data_fd = 0;goto out;}memset(&(client_conn->peer_sockaddr), 0, sizeof(client_conn->peer_sockaddr));client_conn->peer_sockaddr.sin_family = AF_INET;client_conn->peer_sockaddr.sin_port = htons(client_conn->peer_port);client_conn->peer_sockaddr.sin_addr.s_addr = inet_addr(client_conn->peer_ipaddr);if (connect(client_conn->data_fd, (struct sockaddr*)&(client_conn->peer_sockaddr), sizeof(struct sockaddr)) == -1){log_write(LOG_ERROR, "client failed to connect server, errno: %d", errno);close(client_conn->data_fd);SET_ERRNO(client_conn->error);goto out;}//设置超时时间client_conn->conn_timeout = conn_timeout;/*{socklen_t optlen = sizeof(struct timeval);struct timeval tv;printf(">>before set....\n");tv.tv_sec = 10;tv.tv_usec = 0;if (getsockopt(client_conn->data_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, &optlen) != -1){printf("success to getsockopt SO_SNDTIMEO, tv_sec: %d, tv_usec: %d\n", tv.tv_sec, tv.tv_usec);} else {printf("failed to getsockopt.\n");}}*/setsockopt(client_conn->data_fd, SOL_SOCKET, SO_SNDTIMEO, (const char*)&timeout, sizeof(timeout));setsockopt(client_conn->data_fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout));#endif
Tips:注意在设置超时时间的时候,windows 下是 ms 单位,linux 下是 s 单位
总结
这次移植主要是对头文件和 windows 编译程序有更多的了解。
https://blog.csdn.net/kemosisongge/article/details/103593278
