当前位置: 首页 > news >正文

windows c转linux c要做的事情。

写在开头:

最近的copy项目要转到windows版本了,一直在跟进做这个事情。

直入主题说下移植过程中可能涉及以下几个方面的调整:‌

  • 编译器和工具链的更改:‌Windows和Linux使用不同的编译器和工具链,‌因此需要在Windows上安装和配置相应的编译器和工具链。‌
  • 文件路径和文件系统的更改:‌Windows和Linux使用不同的文件系统,‌路径分隔符也不同。‌因此,‌需要更改应用程序中使用的文件路径和文件系统相关的代码。‌
  • 库文件和依赖项的更改:‌应用程序可能会依赖于Linux上特定的库文件和依赖项,‌这些在Windows上可能不存在或与Linux上的版本不兼容。‌因此,‌需要更改代码以使用适当的库文件和依赖项。‌
  • 网络接口的更改:‌Linux和Windows上的网络接口也有所不同,‌因此需要更改应用程序中使用的网络接口相关的代码。‌
  • 系统调用的更改:‌Linux和Windows上的系统调用也不同,‌因此需要更改应用程序中使用的系统调用相关的代码。‌
  • 测试和调试:‌移植完成后需要进行测试和调试,‌以确保应用程序在Windows上能够正常运行。‌

针对以上方向总结细节:

  • 检查源代码是否使用了Linux特有的API或库。
    • 文件系统相关
      • Linux下面,文件换行是"\n",而windows下面是"\r\n"。 

      • Linux下面,目录分隔符是"/",而windows下面是"\"。

      • Linux中可根据stat的st_mode判断文件类型,有S_ISREG、S_ISDIR等宏。

        • Windows中没有,需要自己定义相应的宏,如#define S_ISREG(m) (((m) & 0170000) == (0100000))#define S_ISDIR(m) (((m) & 0170000) == (0040000))

      • Linux中删除文件是unlink,Windows中为DeleteFile

      • 在Windows平台上,可以使用ReadDirectoryChangesW API来监控文件变更
      • 扫描本地目录FindFirstFileFindNextFile方法?

    • 网络相关
      • linux包含#include <sys/socket.h>、#include <netinet/in.h>、#include <netdb.h>、#include <arpa/inet.h>
        windows需要包含#include <winsock.h>
      • #pragma comment (lib, “ws2_32.lib”) //加载 ws2_32.dll   windows socket需要在加载头文件后,加载ws库
      • windows需要初始化socket,调用WSAStartup方法。
      • Linux中关闭socket为close,Windows中为closesocket。
      • 因为linux中的socket与普通的fd一样,所以可以在TCP的socket中,发送与接收数据时,直接使用read和write。windows使用recv和send。
      • Linux 使用“文件描述符”的概念,而 Windows 使用“文件句柄”的概念;Linux 不区分 socket 文件和普通文件,而 Windows 区分;
        • Linux 下 socket() 函数的返回值为 int 类型,而 Windows 下为 SOCKET 类型,也就是句柄。
      • 设置socet选项,比如设置socket为非阻塞的。

        • Linux下为flag = fcntl (fd, F_GETFL);fcntl (fd, F_SETFL, flag | O_NONBLOCK);

        • Windows下为flag = 1;ioctlsocket (fd, FIONBIO, (unsigned long *) &flag);

        • 当非阻塞socket的TCP连接正在进行时,Linux的错误号为EINPROGRESS,Windows的错误号为WSAEWOULDBLOCK。

    • 多线程
      • 头文件(win)process.h --〉(linux)pthread.h
        方法_beginthread --> pthread_create
        _endthread --> pthread_exit
    • 其他
      • Linux为srandom和random,Windows为srand和rand。
      • Linux为snprintf,Windows为_snprintf。
      • Linux为strcasecmp,Windows为_stricmp。
      • Linux下面,通常使用全局变量errno来表示函数执行的错误号。Windows下要使用GetLastError ()调用来取得。
  • 修改源代码中的环境变量访问方式。

  • 确保代码中没有使用Linux下的特殊权限或用户组。

  • 如果程序依赖于外部工具或脚本,需要在Windows上安装这些工具并修改调用方式。

  • 编写或修改Makefile和编译脚本,使其可以在Windows下编译。

另外:

还可以采用一些工具和技术来帮助移植过程,‌如使用跨平台的开发工具和集成开发环境(‌如Visual Studio等)‌来帮助在Windows平台上进行代码编译和调试,‌以及使用虚拟化技术来模拟Linux环境以便在Windows上进行程序测试和调试。‌还有一些第三方的代码转换工具和库可以帮助实现代码的移植和兼容性处理。‌

总的来说,‌将Linux代码转移到Windows平台是一个复杂的过程,‌需要对操作系统和编程语言的细节有深入的了解。‌通过合理的准备工作和采用适当的工具和技术,‌可以实现Linux代码向Windows的转换和移植,‌从而让应用程序能够在不同平台上进行部署和运行。

所以总共有两个方向(使用虚拟化技术模拟linux环境或者vs),三个思路。

方向一

安装gcc,使用vscode

1、windows下安装 MinGW 

MinGW的安装和使用-CSDN博客

此方法是说 gcc没有对windows的支撑,MinGW(mini gnu windows) 对gcc进行了打包封装,使其可以在windows上适用,它包含了make、gcc。

2、使用mingw32-make  编译

3、处理编译问题

方案二

由于代码量不大,可以考虑使用visual stdio。

1、在visual stdio下新建解决方案,zcopy,并新建两个项目 zcopy和 zcopy-ctl

2、将zcopy和zcopy-ctl项目引入代码。

解决方案可以设置启动项目,分别调试和启动,目前zcopy和ctl代码在一个项目,很不方便,所以考虑分开两个项目。

3、编译两个工程处理编译问题。

4、如果用MSVC编译开源库麻烦在于第三方的开源库本身还需要一些依赖库,这些依赖库在windows多数并不提供编译好的二进制版本,所以要先编译安装各种依赖库。

方案三

使用msys2的虚拟化环境

MSYS2 是msys2的一个升级版,准确的说是集成了pacman 和mingw-w64的 cygwin 升级版, 与MSYS最大的区别是移植了 linux的软件包管理系统 pacman(其实是与Cygwin的区别)。

但是我使用这个环境的时候,没有想象中好用,我们项目的支持需要openssl、libevent、glib等支持。前两者适配还好,后面第三个可能是版本问题一直有编译问题。

最终决定:

使用vs的IDE来做这个事情,原因有两点:

  1. 方案1、2第三方虽然说做了很久的支持,但是毕竟微软不是开源的,所以用vs来做应该更靠谱一些,不会出现一些无法解决的问题
  2. 组里人大部分都一直做linux,想感受win的开发环境和方法。哈哈哈哈哈~

完美的解决思路是什么:

win_port

/*-------------------------------------------------------------------------** dirent.c*	  opendir/readdir/closedir for win32/msvc**-------------------------------------------------------------------------*/
#include <win32_port.h>
#include <dirent.h>struct DIR
{char	   *dirname;struct dirent ret;			/* Used to return to caller */HANDLE		handle;
};DIR *
opendir(const char *dirname)
{DWORD		attr;DIR		   *d;/* Make sure it is a directory */attr = GetFileAttributes(dirname);if (attr == INVALID_FILE_ATTRIBUTES){errno = ENOENT;return NULL;}if ((attr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY){errno = ENOTDIR;return NULL;}d = malloc(sizeof(DIR));if (!d){errno = ENOMEM;return NULL;}d->dirname = malloc(strlen(dirname) + 4);if (!d->dirname){errno = ENOMEM;free(d);return NULL;}strcpy(d->dirname, dirname);if (d->dirname[strlen(d->dirname) - 1] != '/' &&d->dirname[strlen(d->dirname) - 1] != '\\')strcat(d->dirname, "\\");	/* Append backslash if not already there */strcat(d->dirname, "*");	/* Search for entries named anything */d->handle = INVALID_HANDLE_VALUE;d->ret.d_ino = 0;			/* no inodes on win32 */d->ret.d_reclen = 0;		/* not used on win32 */d->ret.d_type = DT_UNKNOWN;return d;
}struct dirent *
readdir(DIR *d)
{WIN32_FIND_DATA fd;if (d->handle == INVALID_HANDLE_VALUE){d->handle = FindFirstFile(d->dirname, &fd);if (d->handle == INVALID_HANDLE_VALUE){/* If there are no files, force errno=0 (unlike mingw) */if (GetLastError() == ERROR_FILE_NOT_FOUND)errno = 0;else_dosmaperr(GetLastError());return NULL;}}else{if (!FindNextFile(d->handle, &fd)){/* If there are no more files, force errno=0 (like mingw) */if (GetLastError() == ERROR_NO_MORE_FILES)errno = 0;else_dosmaperr(GetLastError());return NULL;}}strcpy(d->ret.d_name, fd.cFileName);	/* Both strings are MAX_PATH long */d->ret.d_namlen = strlen(d->ret.d_name);/** For reparse points dwReserved0 field will contain the ReparseTag.  We* check this first, because reparse points are also reported as* directories.*/if ((fd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0 &&(fd.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT))d->ret.d_type = DT_LNK;else if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)d->ret.d_type = DT_DIR;elsed->ret.d_type = DT_REG;return &d->ret;
}int
closedir(DIR *d)
{int			ret = 0;if (d->handle != INVALID_HANDLE_VALUE)ret = !FindClose(d->handle);free(d->dirname);free(d);return ret;
}
#include <win32_port.h>
#include <pthread-win32.h>DWORD
pthread_self()
{return GetCurrentThreadId();
}
void
pthread_setspecific(pthread_key_t key, void *val)
{
}void *
pthread_getspecific(pthread_key_t key)
{return 0;
}int
pthread_mutex_init(pthread_mutex_t *mp, void *attr)
{mp->initstate = 0;return 0;
}int
pthread_mutex_lock(pthread_mutex_t *mp)
{/* Initialize the csection if not already done */if (mp->initstate != 1){LONG		istate;while ((istate = InterlockedExchange(&mp->initstate, 2)) == 2)Sleep(0);			/* wait, another thread is doing this */if (istate != 1)InitializeCriticalSection(&mp->csection);InterlockedExchange(&mp->initstate, 1);}EnterCriticalSection(&mp->csection);return 0;
}int
pthread_mutex_unlock(pthread_mutex_t *mp)
{if (mp->initstate != 1)return EINVAL;LeaveCriticalSection(&mp->csection);return 0;
}

http://www.lryc.cn/news/424781.html

相关文章:

  • 【高等代数笔记】002.高等代数研究对象(二)
  • ubuntu服务器部署的mysql本地连不上的问题
  • python redis安装
  • YJ0043定制版抖音电商卷抢购系统带回收商城抖音电商优惠卷投资理财系统
  • 如何选择图片和视频
  • html+css网页制作 电商华为商城首页 ui还原度100%
  • EDAS(企业级应用服务)
  • 简单工厂,工厂方法 和 抽象工厂
  • python 压力测试脚本
  • 【Linux】多线程7——线程池
  • Linux Shell实例
  • Linux~MySQL数据库具体操作
  • Unity WebGL平台Hybrid Generate All报错undefined symbol sendfile
  • Java高级Day28-多线程
  • 0003 保险的会计要素及其计量属性
  • Swift版本控制的艺术:掌握代码演化的魔杖
  • 学习实战:生活垃圾自动识别与分类系统的实现
  • Swift模块化构建:解锁代码重用的金钥匙
  • 【计算机网络】CIDR无分类编址知识学习
  • JavaScript 详解
  • 运维实践01-安装OpenJDK
  • Windows下,C# 通过FastDDS高效通信
  • 【模型】ResNet
  • Objective-C中NSExpression与NSPredicate的协同艺术
  • Apache-JMeter压测工具教程
  • Spring Boot集成selenium实现自动化测试
  • 基于phpstudy对cmseasy5.5进行漏洞复现
  • 【c++】 C语言的输入与输出C++的IO流STL空间配置器
  • 基于Faster-RCNN的停车场空位检测,支持图像和视频检测(pytorch框架)【python源码+UI界面+功能源码详解】
  • Vue3从零开始——带你轻松掌握组件的基本操作