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来监控文件变更
-
扫描本地目录
FindFirstFile
和FindNextFile方法?
-
- 网络相关
- 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。
-
- linux包含#include <sys/socket.h>、#include <netinet/in.h>、#include <netdb.h>、#include <arpa/inet.h>
- 多线程
- 头文件(win)process.h --〉(linux)pthread.h
方法_beginthread --> pthread_create
_endthread --> pthread_exit
- 头文件(win)process.h --〉(linux)pthread.h
- 其他
- 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、2第三方虽然说做了很久的支持,但是毕竟微软不是开源的,所以用vs来做应该更靠谱一些,不会出现一些无法解决的问题
- 组里人大部分都一直做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;
}
相关文章:
windows c转linux c要做的事情。
写在开头: 最近的copy项目要转到windows版本了,一直在跟进做这个事情。 直入主题说下移植过程中可能涉及以下几个方面的调整: 编译器和工具链的更改:Windows和Linux使用不同的编译器和工具链,因此需要在Windo…...

【高等代数笔记】002.高等代数研究对象(二)
1. 高等代数的研究对象 1.4 一元高次方程的求根 a n x n a n − 1 x n − 1 . . . a 1 x a 0 0 a_{n}x^{n}a_{n-1}x^{n-1}...a_{1}xa_{0}0 anxnan−1xn−1...a1xa00 等式左边是一元多项式。 所有一元多项式组成的集合称为一元多项式环。...

ubuntu服务器部署的mysql本地连不上的问题
试过了网上的所有方法,都连不上,可以执行: SELECT user, host, plugin FROM mysql.user WHERE user root; 查一下:plungin这个连接插件是不是auth_socket, auth_socket是只能本地连接的插件,需要修改: ALTER USER root% IDENTIFIED WITH mysql_native_password BY your_pass…...
python redis安装
python redis安装 #方法1、 sudo apt-get install redis-server python 支持包: (其实就一个文件,搞过来就能用) sudo apt-get install python-redis #方法2、 sudo pip install redis...

YJ0043定制版抖音电商卷抢购系统带回收商城抖音电商优惠卷投资理财系统
系统是基于逍遥商城二开的系统,pc手机端都新增了邀请码验证 手机端重新定制的UI,前端产品不至于抖音卷也可以自行更改其他产品 用户前端下单,后台订单可以直接回收,后台支持设置默认邀请码和抢卷时间限制...

如何选择图片和视频
文章目录 1. 概念介绍2. 方法与细节2.1 实现方法2.2 具体细节 3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何选择视频文件"相关的内容,本章回中将介绍如何混合选择图片和视频文件.闲话休提,让我们一起Talk Flutter吧。 1. 概念介绍 我…...

html+css网页制作 电商华为商城首页 ui还原度100%
htmlcss网页制作 电商华为商城首页 ui还原度100% 网页作品代码简单,可使用任意HTML编辑软件(如:Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作)。 获取源码…...

EDAS(企业级应用服务)
1 :介绍 1:edas 提供了应用,开发,部署,监控,运维。同时支持 spring cloud, dubbo ,HSF 2:Ali-Tomcat 基于tomcat改造的Servlet容器。支持原有功能,它在启动时会自动加载Pandora(潘多拉&#x…...
简单工厂,工厂方法 和 抽象工厂
这三种模式, 都是创建类型的模式, 将对象的创建流程封装起来供客户调用 简单工厂模式 简介: 和策略模式一样,就是针对不通的参数, 返回不通的实例而已 问题: 没有遵循开闭原则, 如果我们想增加一种类, 那…...
python 压力测试脚本
需求: 生成一个12位不重复的随机数将随机数赋值给Json 串中的 orderCode字段将Json用ECB 指定 key为bJXQezYtR4ZSNK4p进行加密并作为值传给{ “data”: “” }设置每秒30个并发持续1分钟调用接口接口输出测试测试报告 代码示例 import json import random import…...

【Linux】多线程7——线程池
1.线程池的概念 1.1.池化技术 池化技术指的是提前准备一些资源,在需要时可以重复使用这些预先准备的资源。 在系统开发过程中,我们经常会用到池化技术。通俗的讲,池化技术就是:把一些资源预先分配好,组织到对象池中…...

Linux Shell实例
1.查空行 答案: awk /^$/{print NR} file1.txt#awk:一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析#处理。 #1)基本语法 #awk [选项参数]/pattern1/{action1} /pattern…...
Linux~MySQL数据库具体操作
一、数据库的字符集编码设置 (一)查看数据库默认的字符集 MariaDB [(none)]> show variables like %character%; ------------------------------------------------------ | Variable_name | Value | ------------…...

Unity WebGL平台Hybrid Generate All报错undefined symbol sendfile
详细报错信息如下: Library\Bee\artifacts\WebGL\build\debug_WebGL_wasm\build.js: undefined symbol: sendfile (referenced by top-level compiled C/C code) UnityEditor.BuildPipeline:BuildPlayer (UnityEditor.BuildPlayerOptions) HybridCLR.Editor.Comman…...
Java高级Day28-多线程
83.多线程 什么是线程: 线程右进程创建的,是进程的一个实体 一个进程可以有多个线程 并发:同一个时刻,多个任务交替执行,造成一种貌似同时的错觉 并行:同一个时刻,多个任务同时执行&#x…...
0003 保险的会计要素及其计量属性
与一般行业相同,保险业的会计要素主要包括资产、负债、所有者权益、收入、成本与费用以及利润六个方面。然而,在某些特定的要素上,保险业展示了其独特之处。 资产:由于保险本质上是一种承诺而非实物商品,因此保险业不持…...
Swift版本控制的艺术:掌握代码演化的魔杖
标题:Swift版本控制的艺术:掌握代码演化的魔杖 在Swift开发的世界中,代码的版本管理是一个核心议题。它不仅关系到代码的组织和追踪,更是团队协作和项目持续交付的关键。本文将深入探讨如何在Swift中利用版本管理工具,…...
学习实战:生活垃圾自动识别与分类系统的实现
引言 在日常生活中,垃圾分类是保护环境的重要措施之一。然而,手动分类不仅耗时,还容易出错。基于深度学习的垃圾检测与分类系统能够自动识别和分类不同类型的垃圾,从而提高分类效率。 目录 项目概述 项目背景与意义系统功能介绍…...
Swift模块化构建:解锁代码重用的金钥匙
标题:Swift模块化构建:解锁代码重用的金钥匙 在Swift编程的宏伟蓝图中,模块化不仅是提升代码组织性的关键,更是实现高效开发与维护的法宝。本文将深入探讨Swift模块化构建工具的使用,揭示如何通过模块化将代码转化为可…...
【计算机网络】CIDR无分类编址知识学习
文章目录 1、CIDR引入的背景2、CIDR是什么?2.1 CIDR的2个特点2.2 CIDR斜线记法注意区分细节2.3 路由聚合or构成超网2.4 CIDR里面的掩码(不是叫子网掩码)2.5 CIDR几种等效的记法形式2.6 对于”网络前缀“不是8的整数倍时候,要多加注意 3、CIDR…...

UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...

Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...

JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...

通过MicroSip配置自己的freeswitch服务器进行调试记录
之前用docker安装的freeswitch的,启动是正常的, 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...

图解JavaScript原型:原型链及其分析 | JavaScript图解
忽略该图的细节(如内存地址值没有用二进制) 以下是对该图进一步的理解和总结 1. JS 对象概念的辨析 对象是什么:保存在堆中一块区域,同时在栈中有一块区域保存其在堆中的地址(也就是我们通常说的该变量指向谁&…...