一、前言及背景
1.1需求描述
不同的编程语言,具有不同的编程生态环境,对于项目应用来说,没有最优,只有最适应和最匹配!
这启示了我们一点,没有任何一种语言能综合性的做全栈的事情,各种语言的交互有时是最优的应用方案。
- 比如C++在底层的编程生态非常好:OpenCV、VTK、PCL和OpenCasCade等库在图形和可视化方面傲视,但在构建应用端的调试和
- 而C# 被称为工控之王,这应用端进行界面GUI、通信交互、应用构建时效性方面称霸,如MAUI、WPF、.net core等。
- 而python的交互性语言调试,开放的第三方库生态简直傲视群雄,受到科研和人工智能领域受众追捧。
- 诸如 JAVA、Go等编程领域在web开发等领域也各领风骚。
1.2常见编程语言对比
下面以作应用和算法开发比较常见的三种编程语言来对比体现,各自的优劣,综合场景的需求!
1️⃣定位对比:
项目 | C++ | C# | Python |
---|---|---|---|
语言范式 | 编译型、面向对象、泛型、底层控制 | 编译+托管(IL)、面向对象、泛型、托管环境 | 解释型、动态类型、脚本语言、面向对象 |
开发者定位 | 系统/游戏/高性能开发者 | .NET 平台开发者、桌面/企业/Web开发 | AI、数据科学、自动化、快速开发 |
运行环境 | 无需运行时,直接机器码 | .NET CLR/Mono 运行环境 | Python 解释器(CPython、PyPy等) |
应用领域 | 操作系统、驱动、游戏、嵌入式 | 桌面软件、Web、游戏、企业级应用 | AI、ML、脚本、爬虫、数据分析 |
2️⃣执行过程对比:
维度 | C++ | C# (.NET) | Python |
---|---|---|---|
执行方式 | 编译成机器码,直接运行 | 编译成 CIL,JIT 成机器码 | 解释执行,或 JIT(如 PyPy) |
性能 | 🚀 极高(手动内存管理) | 高(JIT 优化) | 中等到低 |
内存管理 | 手动 / RAII / 智能指针 | GC 自动内存管理 | GC 自动内存管理 |
启动速度 | 快(本地执行) | 中等 | 慢(解释器加载) |
并发模型 | 原生线程,复杂 | 线程 + 异步(Task、async/await) | 多线程受 GIL 限制,支持多进程 |
3️⃣优势与劣势对比
语言 | 优势 | 劣势 |
---|---|---|
C++ | - 性能极致 - 控制精细 - 底层开发唯一选项 - 可用于实时系统 |
- 学习曲线陡峭 - 容易出错(指针、内存泄漏) - 编译慢 |
C# | - 开发效率高 - 面向对象彻底 - 支持泛型、LINQ、异步良好 - 有效利用 .NET 生态 |
- 跨平台初期受限(.NET Core 之后改善) - 与底层交互复杂 |
Python | - 简洁优雅,学习曲线低 - 超强生态(AI、数据分析、自动化) - 丰富第三方库 |
- 速度慢(解释执行) - GIL 限制并发 - 类型检查弱 |
4️⃣应用领域对比
领域 | C++ | C# | Python |
---|---|---|---|
游戏引擎 | ✅ Unreal Engine, Unity底层 | ✅ Unity脚本层 | ❌(仅做工具) |
操作系统/驱动 | ✅ 必须用 | ❌ | ❌ |
企业系统 | ❌ | ✅ .NET 强项 | ✅ 但主要是工具和脚本 |
AI/机器学习 | ❌ | ❌ | ✅ 主流框架如 PyTorch、TF |
脚本 & 自动化 | ❌ | ❌ | ✅ 极其适合 |
嵌入式/芯片开发 | ✅ | ❌ | ❌ |
跨平台 UI | ❌ Qt可用 | ✅ MAUI/.NET 6+ | ✅ PyQt/Tkinter 可行 |
5️⃣互操作性对比
场景 | 建议方案 |
---|---|
C# 调用 C++ | C++/CLI 封装或 P/Invoke |
Python 调用 C++ | ctypes、Cython、PyBind11、Boost.Python |
C# 调用 Python | Python.NET、IronPython(有限支持) |
Python 调用 C# | Python.NET、COM、gRPC |
C++ 调用 C# | C++/CLI 或托管宿主 |
1.3应用背景
从做应用项目的角度,我们常见的考虑因素:
- 项目时间;
- 性能;
- 应用场景;
- 基于生态来进行二次开发;
- 是否允许自己造轮子,做生态;
- 各自语言生态对项目开发的依赖权重;
综合上面因素来考虑,现实中,多语言交互配合是综合场景下的最优解方案!
比如,在性能计算方面,C++和C有着不可比拟的性能优势;在GUI界面开发和应用端交互领域,C# 的WPF/Windowform有着快速构建项目工程的优势;在脚本化运行和生态体验上,python有着傲人的用户群体和开发者。
在一个项目中,如果都有以上的需求的话,我们会这么做:C++开发封装接口给C# 调用, C# 做应用端GUI开发与用户层交互,Python作为云服务或者脚本化运行调用生态!
更多的交互场景是:C++封装底层动态库,给第三方语言(包括C++自身)调用!
二、C++对外接口
2.1C++对外封装
动态库(DLL/so) 和 静态库(LIB/a) 是两种常见的C++代码重用和模块化方式,它们各有优劣,适用于不同场景。
1️⃣基本对比:
类型 | 名称 | 文件扩展名(Windows / Linux) | 说明 |
---|---|---|---|
静态库 | Static Library | .lib / .a |
编译时链接,代码会复制进最终可执行程序 |
动态库 | Dynamic Library(共享库) | .dll / .so |
程序运行时加载,节省可执行文件体积 |
注:文件拓展名在不同系统下,生成后缀不一样!
2️⃣使用方式对比:
项目 | 静态库 .lib/.a |
动态库 .dll/.so |
---|---|---|
链接方式 | 编译期链接,合并进 .exe |
编译期链接 .lib ,运行时需 .dll |
部署依赖 | 单独 .exe 即可运行 |
.exe + .dll 必须一起发布 |
内存使用 | 多进程加载会有多份拷贝 | 多进程共享内存(节省资源) |
更新维护 | 每次更新库都要重新编译主程序 | 可直接替换 .dll ,热更新友好 |
性能差异 | 稍快(少一次跳转) | 稍慢(函数指针调用开销) |
跨语言调用 | ❌ 不便(链接语言相关) | ✅ 容易通过 extern "C" 暴露接口 |
3️⃣常见应用:C++对外封装,总体来说,是以动态链接库为基础,静态库为辅的一个封装应用(静态库生成可选,如果目标平台是C++,大概率使用,目标平台是C#,则不需要 )!
2.2基于目标平台封装接口形式
基于目标平台来决定封装接口形式
,这句话是重点,同样,有多种的封装形式,没有最优,只有最适应!
常见的接口形式有:
- 1.托管方式:运行和依赖 .NET 的 CLR(公共语言运行库)上,具有 GC 等功能;
- 2.非托管方式:使用传统 C++(如 new/delete),没有用到CLR依赖;
- 3.托管与非托管混合:可以同时使用原生 C++(native C++)和 .NET 托管代码(managed code),兼顾性能和使用C# 相关底层库,方便开发!
1️⃣使用对比:
特性 | 托管(Managed) | 非托管(Unmanaged) |
---|---|---|
编译目标 | CIL + JIT 运行在 CLR | 机器码,直接运行 |
内存管理 | 自动(GC) | 手动(new/delete, malloc/free) |
类型系统 | .NET 类型系统(System::String^ ) |
原生类型系统(std::string ) |
调用约定 | 由 CLR 管理 | 由操作系统 / 编译器决定 |
跨语言调用 | 易与 C# / VB.NET 交互 | 不直接支持,需封装 |
2️⃣应用场景对比:
- 如果是需要直接使用CLR,并且C++对外接口是类方式进行封装,首选托管封装;
- 如果是追求性能,不使用CLR,并且对外接口较简单(交互调用简单),内部封装良好,写好数据转换接口,首选非托管封装;
- 如果是兼顾性能和CLR(GC等)使用,比较推荐托管和非托管结合,其实本质就是更大范围的托管而已;
三、系列文章汇总
本文章为C++动态库总概述,下面会把系列文章更新到以下链接:
(更新中ing敬请关注!)
最后,文中若有不足,敬请批评指正!