C++动态链接库封装,供C#/C++ 等编程语言使用——C++动态链接库概述(总)

发布于:2025-06-07 ⋅ 阅读:(13) ⋅ 点赞:(0)

一、前言及背景

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敬请关注!)


最后,文中若有不足,敬请批评指正!