Windows c 和 Linux c 的区别

c 语言本身的区别不大,主要是和系统交互的时候会有差异。

  1. Linux 下是 POSIX 接口,Windows 下是 Win32 API

平台环境

Linux

centos:centos 6.5

编译工具:gcc

Windows

Windows 10

编译工具:vs 2005
Debug:x64

移植开始

1. 创建 vs 工程

  1. 将源代码添加到工程里面
  2. 调试编译代码

2. 解决报错信息

1. 解决头文件报错
  1. unistd.h
  2. dirent.h
  3. pthread.h

2. 声明
  1. 在 Linux 上变量声明可以放在任意位置
  2. Winodws 上的声明必须放在可执行代码之前

3. 换行符
  1. Windows 上的换行符需要改成 CRLF
  2. Linux 上的换行符支持 LF 和 CRLF

4. getpid
  1. Linux 上引入 unistd.h
  2. Windows 上引入 process.h

5. 可变参数
  1. #ifdef _WIN32
  2. #define ARG(fmt, ...) test_arg(fmt, __VA_ARGS__)
  3. #else
  4. #define ARG(fmt, args...) test_arg(fmt, ##args)
  5. #endif

6. getopt

参考连接:https://www.jianshu.com/p/991e554d4861

7. dirname

Windows 上没有 dirname 的函数,所以就只有靠自己写一个

  1. #ifdef _WIN32
  2. char drive[_MAX_DRIVE]; //路径中的盘符,例如"d:"
  3. char dir[_MAX_DIR]; //文件夹,例如"\sample\crt\"
  4. char fname[_MAX_FNAME]; //文件名称,例如"crt_makepath_s"
  5. char ext[_MAX_EXT]; //文件扩展名,例如".c"
  6. errno_t err;
  7. err = _splitpath_s(full_path, drive, _MAX_DRIVE, dir, _MAX_DIR, fname,
  8. _MAX_FNAME, ext, _MAX_EXT); //拆分路径
  9. if (err != 0)
  10. {
  11. printf("Error splitting the path. Error code %d.\n", err);
  12. exit(1);
  13. }
  14. sprintf(full_path, "%s%s", drive, dir); //文件夹全路径,例如"d:\sample\crt\"
  15. #else
  16. dirname(full_path);
  17. #endif

8. openssl

参考链接:https://blog.csdn.net/liudongdong19/article/details/84255554

9. sleep

windows 下是 Sleep,Linux 下是 sleep

  1. #ifdef _WIN32
  2. Sleep(ms)
  3. #else
  4. sleep(s)
  5. #endif

10. socket

在连接 socket 的时候有区别

  1. #ifdef _WIN32
  2. // Windows下连接服务器
  3. WSADATA wsaData;
  4. int timeout = conn_timeout * 1000;
  5. if (client_conn->data_fd != INVALID_SOCKET) {
  6. // log_write(LOG_WARN, "the data_fd is not zero, may be initialised");
  7. printf("the data_fd is not zero, may be initialised\n");
  8. }
  9. if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
  10. {
  11. printf("WSAStartup failed");
  12. SET_ERRNO(client_conn->error);
  13. goto out;
  14. }
  15. client_conn->data_fd = socket(AF_INET, SOCK_STREAM, 0);
  16. if (client_conn->data_fd == INVALID_SOCKET)
  17. {
  18. printf("create socket failed");
  19. SET_ERRNO(client_conn->error);
  20. goto out;
  21. }
  22. memset(&(client_conn->peer_sockaddr), 0, sizeof(client_conn->peer_sockaddr));
  23. client_conn->peer_sockaddr.sin_family = AF_INET;
  24. client_conn->peer_sockaddr.sin_port = htons(client_conn->peer_port);
  25. client_conn->peer_sockaddr.sin_addr.s_addr = inet_addr(client_conn->peer_ipaddr);
  26. if (connect(client_conn->data_fd, (struct sockaddr*)&(client_conn->peer_sockaddr), sizeof(struct sockaddr)) == -1)
  27. {
  28. printf("client failed to connect server, errorno: %d", errno);
  29. closesocket(client_conn->data_fd);
  30. }
  31. setsockopt(client_conn->data_fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(int));
  32. setsockopt(client_conn->data_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(int));
  33. #else
  34. struct timeval timeout = {conn_timeout, 0};
  35. if (client_conn->data_fd != 0) {
  36. log_write(LOG_WARN, "the data_fd is not zero, may be initialised");
  37. }
  38. client_conn->data_fd = socket(AF_INET, SOCK_STREAM, 0);
  39. if (client_conn->data_fd == -1) {
  40. log_write(LOG_ERROR, "client failed to create socket, errno: %d", errno);
  41. SET_ERRNO(client_conn->error);
  42. client_conn->data_fd = 0;
  43. goto out;
  44. }
  45. memset(&(client_conn->peer_sockaddr), 0, sizeof(client_conn->peer_sockaddr));
  46. client_conn->peer_sockaddr.sin_family = AF_INET;
  47. client_conn->peer_sockaddr.sin_port = htons(client_conn->peer_port);
  48. client_conn->peer_sockaddr.sin_addr.s_addr = inet_addr(client_conn->peer_ipaddr);
  49. if (connect(client_conn->data_fd, (struct sockaddr*)&(client_conn->peer_sockaddr), sizeof(struct sockaddr)) == -1){
  50. log_write(LOG_ERROR, "client failed to connect server, errno: %d", errno);
  51. close(client_conn->data_fd);
  52. SET_ERRNO(client_conn->error);
  53. goto out;
  54. }
  55. //设置超时时间
  56. client_conn->conn_timeout = conn_timeout;
  57. /*
  58. {
  59. socklen_t optlen = sizeof(struct timeval);
  60. struct timeval tv;
  61. printf(">>before set....\n");
  62. tv.tv_sec = 10;
  63. tv.tv_usec = 0;
  64. if (getsockopt(client_conn->data_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, &optlen) != -1){
  65. printf("success to getsockopt SO_SNDTIMEO, tv_sec: %d, tv_usec: %d\n", tv.tv_sec, tv.tv_usec);
  66. } else {
  67. printf("failed to getsockopt.\n");
  68. }
  69. }
  70. */
  71. setsockopt(client_conn->data_fd, SOL_SOCKET, SO_SNDTIMEO, (const char*)&timeout, sizeof(timeout));
  72. setsockopt(client_conn->data_fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout));
  73. #endif

Tips:注意在设置超时时间的时候,windows 下是 ms 单位,linux 下是 s 单位

总结

这次移植主要是对头文件和 windows 编译程序有更多的了解。
https://blog.csdn.net/kemosisongge/article/details/103593278