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

跨平台 C++ 开发实战

跨平台 C++ 开发实战

C++ 跨平台开发涉及编译链接、文件系统、并发编程、数据库访问、网络通信、移动端开发等多个技术领域。本文汇总了 C++ 工程开发中的实用技巧,涵盖 GCC 链接配置、C++17 新特性、ORM 框架、HTTP 客户端、Android NDK 开发、JNI 编程、Go 交叉编译等核心主题,帮助开发者高效应对跨平台开发中的常见问题。

[图片占位符:C++ 跨平台开发技术栈]

一、GCC 静态链接与动态链接

# 默认动态链接gcc-oapp main.c-lmysqlclient# 静态链接指定库gcc-oapp main.c -Wl,-Bstatic-lmysqlclient-Wl,-Bdynamic-lpthread-ldl# 静态链接 stdc++gcc-oapp main.cpp -static-libstdc++

注意:使用-Wl,-Bstatic后必须恢复-Wl,-Bdynamic,否则后面所有库都会用静态链接。

二、C++17 filesystem

#include<filesystem>namespacefs=std::filesystem;// 检查文件是否存在fs::exists("/tmp/test.txt");// 遍历目录for(auto&entry:fs::directory_iterator("/tmp")){std::cout<<entry.path()<<std::endl;}// 创建目录fs::create_directories("/tmp/a/b/c");

编译时需要链接-lstdc++fs(部分 GCC 版本需要)。

三、读写锁(shared_mutex)

#include<shared_mutex>typedefstd::shared_lock<std::shared_mutex>read_lock;typedefstd::unique_lock<std::shared_mutex>write_lock;std::shared_mutex smutex;// 读操作(多个线程可同时获取读锁){read_lockrlk(smutex);// 读取数据}// 写操作(只有一个线程能获取写锁){write_lockwlk(smutex);// 修改数据}

四、ODB ORM 框架

ODB 是 C++ 的 ORM(对象关系映射)框架,可以不写 SQL 语句直接操作数据库:

#pragmadbobject(person)classperson{public:#pragmadbmember(id_)idconststd::string&name()const{returnname_;}voidname(conststd::string&name){name_=name;}private:std::string name_;};

注意:成员变量必须要有公共访问接口,且命名有规则(如name_对应name()name(const std::string&))。

五、libcurl HTTP 客户端

#include<curl/curl.h>curl_global_init(CURL_GLOBAL_DEFAULT);// 同步方式(easy)CURL*easy_handle=curl_easy_init();curl_easy_setopt(easy_handle,CURLOPT_URL,"http://example.com/api");curl_easy_perform(easy_handle);// 异步方式(multi)CURLM*multi_handle=curl_multi_init();curl_multi_add_handle(multi_handle,easy_handle);intrunning;curl_multi_perform(multi_handle,&running);curl_global_cleanup();

六、二进制转十六进制

std::stringbin_to_hexstr(uint8_t*bin,std::size_t length){std::stringstream ss;std::for_each(bin,bin+length,[&ss](uint8_tch){ss.fill('0');ss.width(2);ss<<std::hex<<static_cast<uint32_t>(ch);});returnss.str();}

七、STL resize 与 reserve 的区别

std::vector<int>v;// resize:改变 size,多出的元素会被初始化v.resize(10);// size 变为 10,元素初始化为 0v.resize(5);// size 变为 5,多余的元素被销毁v.resize(8,42);// size 变为 8,新增元素填充 42// reserve:改变 capacity,不影响 size,不初始化v.reserve(100);// capacity >= 100,但 size 不变

记忆:resize 和 size 相关,reserve 和 capacity 相关。

八、MinGW-w64 工具链

MinGW-w64 是 Windows 平台的 GNU 工具套件,包含 gcc、g++、gdb 等:

三大 MinGW 发行版的区别:

发行版说明
MinGW最早诞生,只支持 32 位,不推荐
MinGW-w64MinGW 的独立分支,支持 32/64 位,推荐使用
TDM-GCCMinGW-w64 的打包版

安装时注意选择正确的平台:i686为 32 位,x86_64为 64 位。

九、Android NDK 开发

给 Android 编写 C++ 动态库有两种方式:

方式一:使用 Android Studio + NDK

  • 优点:可以调试 C++ 代码
  • 缺点:NDK 占用空间大

方式二:使用 Linux NDK 交叉编译

  • 优点:CMake 支持好,不占用本机空间
  • 缺点:不能调试

关键 CMake 参数:

cmake..\-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake\-DANDROID_ABI=armeabi-v7a\-DANDROID_PLATFORM=android-23

十、JNI 编程要点

JNI 是 Java 调用 C++ 的桥梁,核心流程如下:

  1. 创建 Java 类,声明native方法
  2. 使用javah生成 JNI 头文件
  3. 在 C++ 中实现 JNI 函数

JNI 函数命名规则:

Java_包名_类名_方法名
// JNI 函数实现示例extern"C"JNIEXPORT jstring JNICALLJava_com_example_myapplication_MyDll_stringFromJNI(JNIEnv*env,jobject/* this */){std::string hello="Hello from C++";returnenv->NewStringUTF(hello.c_str());}

JNI 开发要点:

  • 强烈建议用javah生成 JNI,不要手写
  • Java 中通过System.loadLibrary("native-lib")加载 SO 库
  • SO 文件名要去掉lib前缀和.so后缀

十一、Go 交叉编译与 CGO

当 Go 项目使用 CGO 调用 C++ 库时,交叉编译需要配置对应平台的 GCC:

# 编译 32 位程序setGOARCH=386setCGO_ENABLED=1setCC=i686-w64-mingw32-gccsetCXX=i686-w64-mingw32-g++# Linux 下通过环境变量指定链接库CGO_LDFLAGS="/usr/lib/libssl.a /usr/lib/libcrypto.a"go build main.go

注意:libssl.alibcrypto.a的链接顺序不能乱。

十二、VS 中文编码问题

Visual Studio 默认使用 GB2312 编码,建议统一使用 UTF-8:

项目属性 -> C/C++ -> 所有选项 -> 附加选项 -> 添加 /utf-8

/utf-8相当于同时设置/source-charset:utf-8/execution-charset:utf-8

总结

跨平台 C++ 开发需要掌握的技巧非常广泛,以下是需要重点关注的领域:

技术领域关键要点
编译链接理解静态/动态链接的区别,正确使用链接选项
C++17 新特性filesystem 简化文件操作,shared_mutex 支持读写锁
数据库访问ODB 提供 ORM 能力,避免手写 SQL
网络通信libcurl 支持同步/异步 HTTP 请求
移动端开发Android NDK 交叉编译 + JNI 桥接 Java 与 C++
跨语言调用Go CGO 实现 Go 与 C++ 的互操作
编码规范统一使用 UTF-8 编码,避免中文乱码

跨平台开发的核心原则是:尽量使用标准库和跨平台框架,将平台相关代码隔离到独立模块中,通过 CMake 等构建工具管理不同平台的编译配置。

http://www.jsqmd.com/news/672886/

相关文章:

  • 终极指南:如何用KMS_VL_ALL_AIO一键永久激活Windows和Office系统
  • 别再傻傻分不清!一张图看懂MOS管增强型和耗尽型的本质区别
  • 从抛物面天线设计到3D打印:手把手教你用Blender验证旋转抛物面方程的正确性
  • 别再手动切数据源了!用dynamic-datasource-spring-boot-starter 3.3.2实现动态数据源与负载均衡
  • 从IIS到联合托管:一张图看懂ArcGIS Enterprise 10.8在WinServer2016上的完整数据流与端口规划
  • 告别资源冗余!用Unity Addressable的Analyze工具优化你的Bundle包依赖
  • mysql数据库关于表的基础知识
  • 中文图形编程+语音识别,485设备智能化一步到位
  • IDR逆向工程工具:Delphi程序反编译完整指南
  • 【项目实训(个人)】5:完成管理员端及统计功能
  • DCT-Net卡通化模型多语言支持:Gradio界面中英文切换与本地化配置
  • GLM-OCR一键部署教程:基于Ubuntu20.04的快速环境配置指南
  • Gitee DevOps平台:中国企业的数字化研发效能加速器
  • 电脑批量改文件名的4种超实用方法,原来这么简单!
  • memory泄露分析方法(FD泄漏篇)
  • 简易信号失真度测量装置的设计与实现(STM32单片机)
  • 山东大学软件学院项目实训进展记录2
  • 基恩士KV7500/KV8000轴控制FB模板大全:多种定位控制单元适配,PLC编程利器,详细...
  • Dify 客户端插件集成全链路解析(C# 14 + Native AOT 部署终极手册)
  • 发票统计软件:批量OCR识别的神器
  • 2026年3月赛事承办学习机构推荐,比较好的赛事承办推荐10年质保有保障 - 品牌推荐师
  • 在macOS上享受完美歌词体验:LyricsX终极使用指南 [特殊字符]
  • 博士论文不是“本科生Pro版”,好写作AI的“学术脚手架”让孤独的长征有迹可循
  • LVGL官方例程深度调优指南:以lv_demo_widgets为例,释放你的TFT-LCD全部潜力
  • 【LeetCodeHOT100】 160. 相交链表 —— Java多解法详解
  • 保姆级教程:在Ubuntu 20.04上从源码编译运行ORB_SLAM2(附TUM数据集测试)
  • 科研小白第一次向国外实验室要质粒,我的完整邮件模板与催更话术(附避坑经验)
  • Python的__reduce__与__reduce_ex__方法在对象序列化中的定制
  • “像河流一样编程”:从罗素的散文学习如何设计可维护的软件架构与优雅的代码生命周期
  • Dify工作区权限继承链断裂?资深SRE教你用GraphQL动态追溯17级权限依赖关系