news 2026/10/22 18:39:00

CMake FortranCInterface 模块深度解析:C 与 Fortran 混合编程的符号名修饰(Name Mangling)自动检测与头文件生成

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CMake FortranCInterface 模块深度解析:C 与 Fortran 混合编程的符号名修饰(Name Mangling)自动检测与头文件生成
  • 构建工具
  • 开发工具
  • CLI

【免费下载链接】CMake

Mirror of CMake upstream repository

项目地址:https://gitcode.com/gh_mirrors/cm/CMake
点击查看免费下载

FortranCInterface 是 CMake 内置的核心模块,负责自动检测当前工具链下 Fortran 与 C/C++ 交互时使用的符号名修饰(Name Mangling)规则,并生成可直接在 C 源码中使用的头文件宏,从而让 C 侧无需关心 Fortran 编译器是 GNU、Intel、PGI 还是其他厂商。本文以 Modules/FortranCInterface.cmake 的官方文档为骨架,结合 Modules/FortranCInterface/ 目录下的检测工程源码,完整讲解该模块的变量体系、FortranCInterface_HEADER与FortranCInterface_VERIFY两个命令的用法,以及底层符号解析与宏构造的完整原理。读完本文,你将能在自己的混合语言项目里直接复用它生成可靠的跨编译器 C 头文件。

一、为什么需要 FortranCInterface:Fortran 符号修饰问题

Fortran 编译器在生成 C 可链接的符号名时没有统一标准:有的在子程序名后追加一个下划线(mysub_,GNU/Intel),有的前后加双下划线(my_sub__,GNU g77),有的全部大写(MYSUB,Windows 上的 Intel),有的用模块前缀(__mymodule_MOD_mysub,GNU 4.3),还有$分隔(HP、Cray)等五花八门的规则。若在 C 源码里硬编码某个特定编译器的修饰名,项目一旦更换 Fortran 编译器就会链接失败。

FortranCInterface 模块解决的正是在配置阶段自动探测当前 Fortran 编译器的修饰规则,并将结果以 C 预处理器宏的形式固化到生成的头文件中,使 C 代码始终以统一的宏调用方式访问 Fortran 例程。

模块加载与前置条件

在 CMake 工程中通过一行命令加载:

include(FortranCInterface)

从 Modules/FortranCInterface.cmake 的源码可以看到,模块加载后有明确的硬性前置条件:它要求当前工程已经启用C 和 Fortran 两种语言(project(... C Fortran)),否则直接以FATAL_ERROR终止:

foreach(lang C Fortran) if(NOT CMAKE_${lang}_COMPILER_LOADED) message(FATAL_ERROR "FortranCInterface requires the ${lang} language to be enabled.") endif() endforeach()

加载后模块把FortranCInterface_SOURCE_DIR指向 Modules/FortranCInterface 目录,并在${CMAKE_BINARY_DIR}/CMakeFiles/FortranCInterface下创建/复用检测工程;最终通过include(.../Output.cmake)把检测结果变量读入当前作用域。模块通过if(FortranCInterface_SOURCE_DIR) return()保证在同一个工程中只执行一次检测逻辑。

二、检测流程:一个小型 C+Fortran 探针工程如何"自曝"符号

模块核心的检测动作并不神秘:它用try_compile构建一个内含 C 与 Fortran 的迷你工程(源码见 Modules/FortranCInterface/CMakeLists.txt),工程生成的可执行文件内部"埋"着各种可能的修饰名符号,然后 CMake 读取该可执行文件中的字符串,反向解析出真实的修饰规则。完整驱动逻辑在 Modules/FortranCInterface/Detect.cmake。

2.1 探针符号的注入

检测工程会按symbol.c.in模板为每个候选修饰名生成一个 C 函数:

const char* @symbol@(void) { return "INFO:symbol[@symbol@]"; }

即每个候选符号对应的 C 函数体内都嵌有一段INFO:symbol[...]标记字符串(模板见 Modules/FortranCInterface/symbol.c.in)。

全局符号候选列表覆盖了各主流编译器(见 Modules/FortranCInterface/CMakeLists.txt):

set(global_symbols my_sub # VisualAge my_sub_ # GNU, Intel, HP, SunPro, PGI my_sub__ # GNU g77 MY_SUB # Intel on Windows mysub # VisualAge mysub_ # GNU, Intel, HP, SunPro, PGI MYSUB # Intel on Windows ${FortranCInterface_GLOBAL_SYMBOLS} )

模块符号候选列表同样按编译器厂商注释(Modules/FortranCInterface/CMakeLists.txt):

set(module_symbols __my_module_MOD_my_sub # GNU 4.3 __my_module_NMOD_my_sub # VisualAge __my_module__my_sub # GNU 4.2 __mymodule_MOD_mysub # GNU 4.3 ... my_module_mp_my_sub_ # Intel MY_MODULE_mp_MY_SUB # Intel on Windows mymodule$mysub # HP mysub$mymodule_ # Cray _QMmy_modulePmy_sub # LLVMFlang __module_my_module_my_sub # LFortran ${FortranCInterface_MODULE_SYMBOLS} )

值得注意的边界处理:

  • $字符:C 标准不允许$出现在标识符中,检测工程会先用check_source_compiles探测当前 C 编译器是否支持$,不支持则跳过含$的候选符号(Modules/FortranCInterface/CMakeLists.txt 与 L80-L93)。
  • 模块符号仅当 Fortran 编译器支持 F90 时才启用(if(CMAKE_Fortran_COMPILER_SUPPORTS_F90)),否则清空module_symbols。
  • 部分编译器的修饰规则根本无法从 C 侧调用,例如 SunPro 的my_module.my_sub_、PathScale 的MY_SUB.in.MY_MODULE,源码中明确注释了这些例外(Modules/FortranCInterface/CMakeLists.txt)。

Fortran 侧由mysub.f、my_sub.f及mymodule.f90、my_module.f90等文件提供真实符号(如 Modules/FortranCInterface/mymodule.f90 定义module mymodule并声明module procedure mysub);C 侧symbols静态库链接 Fortran 静态库myfort,最终可执行文件FortranCInterface(Modules/FortranCInterface/main.F)调用call_sub/call_mod保证所有符号都被链接进产物,且用!DIR$ NOINLINE阻止编译器内联优化掉调用(Modules/FortranCInterface/call_sub.f)。能实际链接成功的候选符号,其INFO:symbol[...]字符串就会出现在可执行文件里。

2.2 正则解析:从符号反推修饰规则

检测阶段(Modules/FortranCInterface/Detect.cmake)用file(STRINGS ... REGEX "INFO:[A-Za-z0-9_]+\\[[^]]*\\]")从可执行文件中提取至多 8 个INFO:symbol[...]标记,然后用四组正则分别匹配:

set(_global_regex "^(_*)(mysub|MYSUB)([_$]*)$") set(_global__regex "^(_*)(my_sub|MY_SUB)([_$]*)$") set(_module_regex "^([A-Za-z_$]*)(mymodule|MYMODULE)([A-Za-z_$]*)(mysub|MYSUB)([_$]*)$") set(_module__regex "^([A-Za-z_$]*)(my_module|MY_MODULE)([A-Za-z_$]*)(my_sub|MY_SUB)([_$]*)$")

以及两套"符号在前、模块在后"的反向正则(Cray 编译器把符号放在模块名之前),从而支持MODULE_THEN_SYMBOL与SYMBOL_THEN_MODULE两种顺序。匹配成功的符号被拆解为 PREFIX / MIDDLE / SUFFIX / CASE 等组成部分,并据此构造宏(Modules/FortranCInterface/Detect.cmake)。

检测完成后打印总结信息,例如:

-- Detecting Fortran/C Interface -- Found GLOBAL and MODULE mangling

结果写入${CMAKE_BINARY_DIR}/CMakeFiles/FortranCInterface/Output.cmake,供模块加载时include(模板见 Modules/FortranCInterface/Output.cmake.in)。检测只在首次配置或相关输入变化时重新执行(Detect.cmake通过比较 Output.cmake 与 Input.cmake、模板及自身源码的时间戳决定是否跳过)。

三、结果变量:如何读取检测到的修饰规则

3.1 结果变量(Result Variables)

include(FortranCInterface)之后,以下两个布尔变量标识修饰规则是否被识别:

变量含义
FortranCInterface_GLOBAL_FOUND全局子程序和函数(global subroutines/functions)的修饰规则是否已知
FortranCInterface_MODULE_FOUND模块子程序和函数(由MODULE PROCEDURE声明)的修饰规则是否已知

两者都需要对应范畴的"无下划线"与"带下划线"两类符号同时被识别才置 1(见 Modules/FortranCInterface/Detect.cmake)。典型结果是GLOBAL找到而MODULE未找到(例如不支持 F90 的编译器),此时FortranCInterface_MODULE_FOUND=0。

3.2 输入/检测变量(Input Variables)

以下变量描述检测到的修饰规则细节,常规用法不需要直接引用它们(直接用后面的命令即可),但理解它们有助于读懂生成的宏:

全局符号(global,无下划线形式)

变量说明
FortranCInterface_GLOBAL_PREFIX无下划线全局符号的前缀
FortranCInterface_GLOBAL_SUFFIX无下划线全局符号的后缀
FortranCInterface_GLOBAL_CASE大小写形式,UPPER或LOWER

全局符号(global,带下划线形式)

变量说明
FortranCInterface_GLOBAL__PREFIX带下划线全局符号的前缀
FortranCInterface_GLOBAL__SUFFIX带下划线全局符号的后缀
FortranCInterface_GLOBAL__CASE大小写形式,UPPER或LOWER

模块符号(module,无下划线形式)

变量说明
FortranCInterface_MODULE_PREFIX无下划线模块符号的前缀
FortranCInterface_MODULE_MIDDLE出现在模块名与符号名之间的中间部分
FortranCInterface_MODULE_SUFFIX无下划线模块符号的后缀
FortranCInterface_MODULE_CASE大小写形式,UPPER或LOWER
FortranCInterface_MODULE_ORDER组件顺序(CMake 4.1 起):MODULE_THEN_SYMBOL(<PREFIX><module><MIDDLE><symbol><SUFFIX>)或SYMBOL_THEN_MODULE(<PREFIX><symbol><MIDDLE><module><SUFFIX>)

模块符号(module,带下划线形式):对应变量为FortranCInterface_MODULE__PREFIX、FortranCInterface_MODULE__MIDDLE、FortranCInterface_MODULE__SUFFIX、FortranCInterface_MODULE__CASE、FortranCInterface_MODULE__ORDER,语义同上。

此外,Output.cmake.in 还会回填每个范畴实际识别出的原始符号(FortranCInterface_GLOBAL_SYMBOL等)和可直接展开的宏体(FortranCInterface_GLOBAL_MACRO等)。

3.3 扩展修饰规则:FortranCInterface_GLOBAL_SYMBOLS/FortranCInterface_MODULE_SYMBOLS

模块内置的候选列表无法覆盖未来或小众编译器,因此提供两个在include(FortranCInterface)之前设置的列表变量,用于追加候选修饰名(针对MySub、My_Sub、MyModule:MySub、My_Module:My_Sub四类符号):

set(FortranCInterface_GLOBAL_SYMBOLS mysub_ my_sub__ MYSUB_) # ^^^^^ ^^^^^^ ^^^^^ set(FortranCInterface_MODULE_SYMBOLS __mymodule_MOD_mysub __my_module_MOD_my_sub) # ^^^^^^^^ ^^^^^ ^^^^^^^^^ ^^^^^^ include(FortranCInterface)

示例中的^仅为标注原始符号名位置,实际书写不需要。这两个变量会被 Modules/FortranCInterface/Input.cmake.in 透传给检测工程,追加进global_symbols/module_symbols候选列表并参与符号解析。可以推断,这是扩展模块以支持新编译器的最主要途径。

四、FortranCInterface_HEADER:一键生成 C 头文件宏

这是模块最常用的命令,作用是根据检测结果生成一个包含符号修饰宏的 C 头文件。命令签名:

FortranCInterface_HEADER( <file> [MACRO_NAMESPACE <macro-ns>] [SYMBOL_NAMESPACE <ns>] [SYMBOLS [<module>:]<function> ...] )

生成的<file>默认位于${CMAKE_CURRENT_BINARY_DIR}(绝对路径则原样使用,见 Modules/FortranCInterface.cmake),内容基于 Modules/FortranCInterface/Macro.h.in 模板,用configure_file展开。头文件会定义四类宏:

#define FortranCInterface_GLOBAL (name,NAME) ... #define FortranCInterface_GLOBAL_(name,NAME) ... #define FortranCInterface_MODULE (mod,name, MOD,NAME) ... #define FortranCInterface_MODULE_(mod,name, MOD,NAME) ...

四类宏分别对应四类 Fortran 符号的修饰:

宏对应 Fortran 调用形式
GLOBAL无下划线的全局符号:call mysub()
GLOBAL_带下划线的全局符号:call my_sub()
MODULE无下划线的模块符号:use mymod; call mysub()
MODULE_带下划线的模块符号:use mymod; call my_sub()

如果某一类别的修饰规则未被检测到,对应宏不会被定义(生成逻辑见 Modules/FortranCInterface.cmake),调用方代码需用#ifdef防护。所有宏要求同时传入小写与大写两种形式的原始名(宏体内部按检测到的CASE选用name或NAME)。

4.1 三个选项详解

  • MACRO_NAMESPACE <macro-ns>:替换默认的FortranCInterface_前缀。例如MACRO_NAMESPACE "FC_"生成FC_GLOBAL()、FC_GLOBAL_()、FC_MODULE()、FC_MODULE_()。
  • SYMBOL_NAMESPACE <ns>:为SYMBOLS生成的每个预处理器定义加上统一前缀。
  • SYMBOLS:给出需要自动修饰的符号列表,为每个符号生成#define:
<function> ==> #define <ns><function> ... <module>:<function> ==> #define <ns><module>_<function> ...

如果某个符号的修饰规则未知,则不生成定义并输出AUTHOR_WARNING警告("No FortranCInterface mangling known for ...",见 Modules/FortranCInterface.cmake)。

从源码看,SYMBOLS中的符号按是否含_自动归类到"带下划线/不带下划线"形式(if("${f}" MATCHES "_")),含:的条目按<module>:<function>拆分为模块符号,随后直接复用对应的GLOBAL/MODULE宏生成一行#define。

4.2 生成的宏展开效果

以 GNU gfortran 为例(检测到的典型规则为mysub_、my_sub_、__mymodule_MOD_mysub、__my_module_MOD_my_sub),默认命名空间下宏展开约等价于:

#define FortranCInterface_GLOBAL(name,NAME) name##_ #define FortranCInterface_GLOBAL_(name,NAME) name##_ #define FortranCInterface_MODULE(mod_name,name, mod_NAME,NAME) __##mod_name##_MOD_##name##_ #define FortranCInterface_MODULE_(mod_name,name, mod_NAME,NAME) __##mod_name##_MOD_##name##_

实际宏体由 Modules/FortranCInterface/Detect.cmake 依据解析出的 PREFIX/SUFFIX/MIDDLE/CASE/ORDER 动态拼接(含##连接符),因此不同编译器下完全自适应。

4.3 基本用法示例

示例 1:生成仅含四类修饰宏的头文件FC.h:

include(FortranCInterface) FortranCInterface_HEADER(FC.h MACRO_NAMESPACE "FC_")

示例 2:在宏之外,再为具体符号生成自动修饰定义FC_mysub和FC_mymod_my_sub:

include(FortranCInterface) FortranCInterface_HEADER( FCMangle.h MACRO_NAMESPACE "FC_" SYMBOL_NAMESPACE "FC_" SYMBOLS mysub mymod:my_sub )

C 侧用法示意(生成头文件后 include 并调用):

#include "FCMangle.h" /* 调用全局子程序 mysub */ FC_GLOBAL(mysub, MYSUB)(); /* 调用模块 mymod 中的子程序 my_sub */ FC_MODULE(mymod, my_sub, MYMOD, MY_SUB)(); /* 或者直接使用 SYMBOLS 生成的符号定义 */ FC_mysub(); FC_mymod_my_sub();

五、FortranCInterface_VERIFY:编译期验证编译器互操作性

Fortran 与 C 编译器即使各自正常,组合在一起也可能因 ABI、运行时库等差异而链接失败。FortranCInterface_VERIFY用于在构建早期就验证这一组合可用,避免错误在构建末期才爆发。签名:

FortranCInterface_VERIFY([CXX] [QUIET])

5.1 行为说明

  • 不带CXX:验证 Fortran 与 C 的组合;带CXX:验证 Fortran 与 C++ 的组合(要求工程已启用 C++)。
  • 验证方式:用try_compile构建 Modules/FortranCInterface/Verify 目录下的样例工程(一个用 C 语言写main、链接 Fortran 静态库的小程序,见 Modules/FortranCInterface/Verify/CMakeLists.txt;C++ 模式下额外编译 VerifyCXX.cxx 并enable_language(CXX))。该样例工程内部同样会include(FortranCInterface)并生成头文件验证宏。
  • 结果存入缓存变量FortranCInterface_VERIFIED_C或FortranCInterface_VERIFIED_CXX(布尔值),同一配置只验证一次(if(NOT DEFINED FortranCInterface_VERIFIED_${lang})短路)。
  • 验证工程按Release配置构建(set(CMAKE_TRY_COMPILE_CONFIGURATION Release),见 Modules/FortranCInterface.cmake)。
  • 失败行为:不带QUIET时,命令以FATAL_ERROR终止构建,错误信息包含 Fortran 编译器路径、C/C++ 编译器路径以及完整构建输出(Modules/FortranCInterface.cmake);带QUIET时仅记录失败结果,由调用方自行处理。

5.2 典型用法

include(FortranCInterface) # 早期停止不兼容组合,失败则报错退出 FortranCInterface_VERIFY() # 或者静默检查 C++ 组合,由业务逻辑决定后续行为 FortranCInterface_VERIFY(CXX QUIET) if(NOT FortranCInterface_VERIFIED_CXX) message(WARNING "Fortran/C++ combination not supported; skipping feature") endif()

验证过程中的中间输出(构建日志)会被写入${FortranCInterface_BINARY_DIR}/Verify${lang}/output.txt,便于排查失败原因(Modules/FortranCInterface.cmake)。

六、平台与编译器适配细节(源码级补充)

6.1 MinGW 路径特殊处理

MinGW 的 make 工具无法正确处理路径中的(),因此当检测工程目录含括号时,模块会把 Modules/FortranCInterface 目录整体复制到${CMAKE_BINARY_DIR}/CMakeFiles/FortranCInterfaceMinGW后再使用(Modules/FortranCInterface.cmake)。

6.2 macOS 多架构限制

无论检测(Detect.cmake)还是验证(FortranCInterface_VERIFY),都会从CMAKE_OSX_ARCHITECTURES中只取第一个架构传给try_compile,以避免重复输出信息并简化符号解析(如 Modules/FortranCInterface/Detect.cmake)。源码中以FIXME注释标明目前尚无把全部架构转发给try_compile的选项。

6.3 GNU gfortran ≥ 12 的 IPO 规避

GCC gfortran 12 及以上版本若启用 IPO(LTO),会混淆可执行文件中用于正则匹配的返回字符串,导致符号解析失败。因此检测工程针对 GNU Fortran ≥ 12 做了专门处理:给FortranCInterface目标加-fno-lto,给静态库加-flto=auto -ffat-lto-objects(非 Apple 平台),既保证探测字符串不被混淆,又确保验证环节作用于 IPO 对象(Modules/FortranCInterface/CMakeLists.txt)。

6.4 模块初始化符号

PGI 与 Cray(≥ 7.3.2)的 Fortran 编译器需要模块初始化符号,因此检测工程额外提供mymodule_、my_module_、MYMODULE、MY_MODULE等 C 侧符号(PathScale 除外,因为其模块符号含.in.无法从 C 提供)(Modules/FortranCInterface/CMakeLists.txt)。

6.5 链接器语言

验证工程中main由 C 定义,因此不启用 C++ 时显式把VerifyFortranC目标的LINKER_LANGUAGE设为 C,保证用 C 链接器完成链接(Modules/FortranCInterface/Verify/CMakeLists.txt)。

七、完整实战模板

把以上内容组合进一个真实的混合语言项目:

cmake_minimum_required(VERSION 3.28) project(NumLib VERSION 1.0 LANGUAGES C Fortran) # 1) 加载模块并启用 C++ 验证(可选) include(FortranCInterface) FortranCInterface_VERIFY(CXX) # 2) 生成头文件:定义 FC_ 命名空间的四类宏, # 并为具体符号生成 FC_foo / FC_bar_my_sub 定义 FortranCInterface_HEADER( ${CMAKE_CURRENT_BINARY_DIR}/FortranMangle.h MACRO_NAMESPACE "FC_" SYMBOL_NAMESPACE "FC_" SYMBOLS foo bar:my_sub ) # 3) 在 C/C++ 侧 include 该头文件并调用 add_executable(app main.c) target_include_directories(app PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_link_libraries(app PRIVATE numlib)

对应 C 源码main.c:

#include <FortranMangle.h> /* 调用全局子程序 foo() */ FC_foo(); /* 调用模块 bar 中的 my_sub(),宏内部自动按编译器规则修饰 */ FC_bar_my_sub(); /* 通用写法:手工展开形式,供没有 SYMBOLS 的场景使用 */ FC_GLOBAL(foo, FOO)(); FC_MODULE(bar, my_sub, BAR, MY_SUB)();

在构建目录执行cmake .. && cmake --build .,配置阶段即可看到探测信息(如-- Found GLOBAL and MODULE mangling)与验证结果;头文件按当前工具链自动生成,切换编译器后重新配置即可无缝适配。

八、小结与进一步探索

FortranCInterface 的价值在于把"Fortran 编译器符号修饰差异"这一平台性问题从源码层彻底隔离:检测期通过探针工程自动识别规则,使用期通过 C 预处理器宏透明适配。关键结论速查:

  • 使用前提:工程必须启用 C 与 Fortran 两种语言;
  • 结果判定:FortranCInterface_GLOBAL_FOUND/FortranCInterface_MODULE_FOUND;
  • 常用命令:FortranCInterface_HEADER生成头文件,FortranCInterface_VERIFY提前验证编译器互操作;
  • 扩展机制:在include前设置FortranCInterface_GLOBAL_SYMBOLS/FortranCInterface_MODULE_SYMBOLS追加候选修饰名;
  • 失败语义:未识别类别的宏不生成、未识别符号不生成定义并告警、验证失败默认FATAL_ERROR。

若需深入研读,可继续查看 Modules/FortranCInterface/Detect.cmake(检测与解析)、Modules/FortranCInterface/CMakeLists.txt(候选符号与编译器特例)、Modules/FortranCInterface/Verify(验证样例工程),以及模块在 CMake 自身测试套件中的集成用法(可检索Tests目录下对FortranCInterface的引用)。

  • 构建工具
  • 开发工具
  • CLI

【免费下载链接】CMake

Mirror of CMake upstream repository

项目地址:https://gitcode.com/gh_mirrors/cm/CMake
点击查看免费下载
上一篇:serial-display-module图片显示完全教程:用show_pic快速切换屏幕图片ID
下一篇:Godot-MCP 故障排查清单:连接失败、命令报错、更改不生效的 8 种解决方案

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/16 8:03:40

网页测试与网站测试:从页面到全站,系统梳理测试重点与流程

网页测试和网站测试&#xff0c;在我这些年做测试的过程中&#xff0c;被混着讲的情况见过太多。刚转测试的同学很容易以为网页测试就是打开页面点点点&#xff0c;网站测试就是把所有页面过一遍。如果只这么理解&#xff0c;最后的测试方案多半是一张没有重点的检查表&#xf…

作者头像 李华
网站建设 2026/10/16 10:30:08

搜索算法剪枝实战:可行性、最优性、记忆化与启发式优化指南

1. 从一个"跑不动"的搜索场景说起很多人第一次接触搜索算法&#xff0c;都是从八皇后、数独、迷宫寻路这类经典问题开始的。写出来的代码在小规模数据上跑得飞快&#xff0c;可一旦把规模放大——比如数独从 99 变成 1616&#xff0c;或者迷宫从 1010 变成 100100——…

作者头像 李华
网站建设 2026/10/16 8:23:17

gRPC传输机制本质:借HTTP/2之壳,行RPC之事

1. 项目概述&#xff1a;gRPC底层传输机制的本质不是“用HTTP2”&#xff0c;而是“借HTTP2的壳&#xff0c;做RPC的事”如果你刚接触gRPC&#xff0c;大概率会被官方文档里那句“gRPC基于HTTP/2”带偏——以为它只是把传统REST API换了个协议跑。我带过不少刚从Spring Boot转过…

作者头像 李华