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

CMake构建学习笔记20-iconv库的构建

1. 构建

iconv是一个用于在不同字符编码(如 UTF-8、GBK、ISO-8859-1 等)之间进行转换的开源库。笔者在《c++中utf8字符串和gbk字符串的转换》这篇文章中介绍过如何在Windows下实现utf8字符串和gbk字符串的转换,不过该实现是基于Win32 API的,在其他平台中是无法使用的。如果需要跨平台,那么就需要使用iconv这样的库来统一实现。

不过麻烦的是iconv是GNU/Linux项目提供的库,不提供CMake的构建方式,以及原生的MSCV的构建方式。在Windows下的构建官方推荐使用MSYS2来进行构建。不过MSYS2构建出来的成果不一定能与MSVC构建的成果二进制兼容,而在Windows下还是使用MSVC的情况比较多。所以这就有点僵住了,只能寻求第三方的帮助。

这里笔者的解决方案是直接使用vcpkg。vcpkg是微软开发的C/C++跨平台开源库管理工具,试用了一下,感觉确实比以前进步很多,如果不是像笔者一样有自己的需求,完全可以都使用vcpkg来安装依赖库。

通过以下指令下载并安装iconv:

git clone https://github.com/microsoft/vcpkg
cd vcpkg
.\bootstrap-vcpkg.bat
.\vcpkg install libiconv:x64-windows

iconv就会安装在vcpkg的目录下,如下图所示:

iconv是个底层库,不需要其他依赖库,因此可以直接复制到笔者的仓库中使用,算是满足了笔者的需求。另外,不知道vcpkg的机制是什么,vcpkg确实也使用了cmake来构建,因为生成了cmake的配置文件,可以直接被CMake项目集成使用。最后,默认情况下vcpkg会检测环境内的VS,使用最高版本的VS来编译链接,构建的时候要保证与目标版本一致。

2. 示例

最后就直接给一个CMake项目调用刚才安装好的iconv库的示例吧。因为vcpkg在安装iconv的时候,也安装了相应的cmake的配置文件,所以可以直接在CMakeLists.txt集成,关键配置代码是:

# 项目代码设置为utf-8编码
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")message(">> using Clang")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")message(">> using GCC")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")message(">> using Intel C++")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")message(">> using Visual Studio C++")add_compile_options("/utf-8")
else()message(">> unknow compiler.")
endif()find_package(Iconv REQUIRED)# ...target_link_libraries(${PROJECT_NAME} PRIVATE Iconv::Iconv)

注意,find_package要生效,需要保证CMake能够搜索到相应的库。如果是直接使用的vcpkg,那么需要将vcpkg集成到CMake搜索路径中:

vcpkg integrate install

如果是像笔者一样,是将iconv复制到自己仓库中使用,那么需要在CMake的内置变量CMAKE_PREFIX_PATH中增加自己的仓库路径(比如修改CMakePresets.json文件中CMAKE_PREFIX_PATH的配置)。

将utf8编码字符串转换成gbk字符串的代码示例如下:

#include <iconv.h>using namespace std;int main() {// 原始 UTF-8 字符串const char *utf8_str = "你好,世界!";printf("%s\n", utf8_str);size_t in_bytes_left = strlen(utf8_str);char in_buf[1024];strcpy(in_buf, utf8_str);char *in_ptr = in_buf;// 输出缓冲区(GBK)char out_buf[1024];char *out_ptr = out_buf;size_t out_bytes_left = sizeof(out_buf);// 打开 iconv 转换器:从 UTF-8 转换到 GBKiconv_t cd = iconv_open("GBK", "UTF-8");if (cd == (iconv_t)-1) {perror("iconv_open failed");return 1;}// 执行转换if (iconv(cd, &in_ptr, &in_bytes_left, &out_ptr, &out_bytes_left) ==(size_t)(-1)) {perror("iconv failed");iconv_close(cd);return 1;}// 关闭转换器iconv_close(cd);// 获取实际转换后的长度size_t converted_len = sizeof(out_buf) - out_bytes_left;// 直接写入二进制字节到 stdout(不经过 printf,防止转码)fwrite(out_buf, 1, converted_len, stdout);return 0;
}

运行结果如下所示:

浣犲ソ锛屼笘鐣岋紒
你好,世界!
http://www.xdnf.cn/news/18818.html

相关文章:

  • 算法概述篇
  • 游戏空间划分技术
  • 日语学习-日语知识点小记-构建基础-JLPT-N3阶段(20):文法+单词第7回2
  • 广告推荐模型1:逻辑回归(Logistic Regression,LR)
  • 如何拯救一家濒临破产的科技公司?
  • 技术总结:AArch64架构下Jenkins Agent(RPM容器编译节点)掉线问题分析与排查
  • KubeBlocks for Oracle 容器化之路
  • 【RAGFlow代码详解-30】构建系统和 CI/CD
  • 微服务-28.配置管理-共享配置
  • poi生成word固定表格列宽
  • TensorFlow 面试题及详细答案 120道(61-70)-- 高级特性与工具
  • css3背景线性渐变:linear-gradient
  • 【密集目标检测】停车场车辆(车位)识别数据集:12k+图像,yolo标注
  • 04 网络信息内容安全--入侵检测技术
  • 依托边缘计算方案,移动云全面化解算力、效率、安全平衡难题
  • from中烟科技翼支付 面试题2
  • 高频面试题:说一下线程池吧?(线程池原理,核心参数,创建方式,应用场景都要说到才能让面试官心服口服)
  • Pytorch深度学习(小土堆)
  • Java 企业应用单点登录(SSO)实现方案详解
  • 如何对springboot mapper 编写单元测试
  • Ansible 文件管理与 Jinja2 模板全解析:从模块应用到动态配置生成
  • 由倍讯科技研制的CCLinkIE转ModbusTCP网关,可达成与脉冲计数器的连接
  • JVM分层编译深度解析:完整机制与实践指南
  • 《零基础入门AI:长短期记忆网络(LSTM)与门控循环单元(GRU)(原理、结构与实现)》
  • 【大前端】实现一个前端埋点SDK,并封装成NPM包
  • 【机械故障】旋转机械故障引起的振动信号调制效应概述
  • 在线教育系统源码助力教培转型:知识付费平台开发的商业实践
  • 达索 Enovia 许可管理技术白皮书:机制解析与智能优化实践
  • 面试 总结(1)
  • 项目集升级:顶部导览优化、字段自定义、路线图双模式、阶段图掌控、甘特图升级、工作量优化、仪表盘权限清晰