admin管理员组

文章数量:1613769

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. 可变参数
#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/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/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编译程序有更多的了解。

本文标签: LinuxWindows