Linux 移植 Windows 的 C++ 代码
conio.h 头文件
移植简述
conio.h 不是 C 标准库中的头文件,在 ISO 和 POSIX 标准中均没有定义。conio 是 Console Input/Output(控制台输入输出)的简写,其中定义了通过控制台进行数据输入和数据输出的函数,主要是一些用户通过按键盘产生的对应操作,比如 getch() 函数等等。大部分 DOS、Windows、Phar Lap、DOSX,OS/2 等平台上的 C 编译器提供了此头文件,UNIX 和 Linux 平台的 C 编译器本身通常不包含此头文件。另外在项目开发中,平时主要是使用 conio.h 这个头文件中的 getch() 函数,即读取键盘字符但是不显示出来(without echo),但是含有 conio.h 的代码在 Linux 下无法直接编译通过,因为 Linux 没有这个头文件。但 Linux 平台下完全可以使用 ncurses 替代 conio.h 头文件,ncurses 支持的 API 可以阅读 官方文档。值得一提的是,ncurses 在 Linux 平台实现了 getch()、scanw()、getstr() 等函数。
安装依赖
提示
由于 ncurses 不是 Linux 系统默认的库,因此需要安装后才能使用,不同平台的安装命令如下:
- CentOS/Fedora
1 | # yum install -y ncurses ncurses-devel |
- Debian/Ubuntu
1 | # apt-get install -y libncurses5-dev libncursesw5-dev |
案例代码
提示
ncurses.h 与 curses.h 这两个头文件是等价的
1 |
|
编译说明
由于 ncurses 不是 Linux 系统默认的库,因此编译时需要链接到该库,同时还需要在 C++ 的源文件里添加头文件 ncurses.h,否则编译会失败。
提示
为了可以正常编译使用了 ncurses 的项目代码,不同构建工具的使用说明如下:
若使用 G++ 编译 C++ 项目,则编译命令的示例如下:
1 | # 编译代码 |
若使用 CMake 构建 C++ 项目,则 CMakeLists.txt 配置文件的示例内容如下:
1 | set(CMAKE_CXX_FLAGS "-std=c++11 -lncurses") |
itoa () 函数
移植简述
在 Window 平台里,itoa() 函数可以将整数转换为字符串,其函数的原型如下。Linux 平台中只有 atoi() 函数,并没有对应的 itoa() 函数,但可以使用 sprintf() 或者 snprintf() 函数替代,建议使用更安全的 snprintf()。
itoa () 函数
函数原型:char *itoa( int value, char *string,int radix)
函数功能:将整数 value 转换成字符串存入 string 指向的内存空间,radix 为转换时所用基数 (保存到字符串中的数据的进制基数)
函数的参数:value:转换的数据,string:目标字符串的地址,radix:转换后的进制数,可以是 10 进制、16 进制等,范围必须在 2-36 之间
snprintf () 函数
头文件:#include <stdio.h>
函数原型:int snprintf(char *str, size_t size, const char *format, ...)
函数功能:将可变参数 ... 按照 format 格式化成字符串,然后将其复制到 str 中
函数参数:str:目标字符串,size:拷贝字节数(Bytes),format:格式化字符串,... 可变参数
案例代码
1 |
|
程序运行的输出结果如下:
1 | str = 12, size = 2 |
strcpy_s () 函数
移植简述
在 Window 平台上,strcpy_s() 函数存在于 #include <cstring> 头文件中。Linux 平台没有该函数,但可以使用 Safe C Library 替代实现。Safe C Library 这个库是在 libc 的基础之上实现了安全的 C11 Annex K 函数,这些函数是它们所缺少的,可以帮助缓解不断增加的安全攻击,特别是缓冲区溢出。
安装依赖
提示
- 由于
Safe C Library不是 Linux 系统默认的库,因此需要安装后才能使用,其默认的安装目录如下 /usr/local/lib/:包含静态库和动态链接库文件/usr/local/include/libsafec:包所有含头文件
1 | # 下载文件(这里下载的不是源码压缩包) |
值得一提的是,Safe C Library 编译后会单独生成静态库文件 /usr/local/lib/libsafec-3.6.0.a 和动态链接库文件 /usr/local/lib/libsafec-3.6.0.so.3.0.6,其中的 3.6.0 是指版本号。
案例代码
提示
strcpy_s()函数在Safe C Library里的safe_str_lib.h头文件中声明
1 |
|
编译说明
由于 Safe C Library 不是 Linux 系统默认的库,因此编译时需要链接到该库,同时还需要在 C++ 的源文件里添加头文件 <libsafec/safe_str_lib.h>,否则编译会失败。
提示
- 为了可以正常编译使用了
Safe C Library的项目代码,不同构建工具的使用说明如下所示 - 可以将上面构建生成的
libsafec-3.6.0.a静态库文件和.h头文件都拷贝到项目里,这样就可以方便在不同的 Linux 系统编译和运行项目,不用每次切换系统时都要重新安装Safe C Library
若使用 G++ 编译 C++ 项目,则编译命令的示例如下,请自行更改库文件的版本号:
1 | # 编译代码 |
若使用 CMake 构建 C++ 项目,则 CMakeLists.txt 配置文件的示例内容如下,请自行更改库文件的版本号:
1 | link_libraries(/usr/local/lib/libsafec-3.6.0.a) |
函数可变参数宏
移植简述
在 Windows 平台与 Linux 平台,函数可变参数宏定义的语法是不一样的。
案例代码
- Windows 平台的函数可变参数宏定义的写法如下,使用的是
__VA_ARGS__
1 | FILE* logfile = fopen("syslog.txt", "w"); |
- Linux 平台的函数可变参数宏定义写法如下,使用的是
##__VA_ARGS__
1 | FILE* logfile = fopen("syslog.txt", "w"); |
