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 _WIN32
char 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\"
#else
dirname(full_path);
#endif
8. openssl
参考链接:https://blog.csdn.net/liudongdong19/article/details/84255554
9. sleep
windows 下是 Sleep,Linux 下是 sleep
#ifdef _WIN32
Sleep(ms)
#else
sleep(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));
#else
struct 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