科学计算【免费下载链接】qiskitQiskit is an open-source SDK for working with quantum computers at the level of extended quantum circuits, operators, and primitives.项目地址https://gitcode.com/gh_mirrors/qi/qiskit点击查看免费下载qiskit-bindgen是 Qiskit 仓库中一个内部 Rust 库负责解析qiskit-cext的 Rust 源码并自动产出可直接安装使用的 C 头文件同时维护自定义头文件目录include、Rust 模板 cratepyo3-ffi及两者的安装逻辑。阅读本文后你将理解 Qiskit C APIQk*前缀符号体系从 Rust 源码到qiskit/types.h、qiskit/funcs.h再到 Rustqiskit-pyo3-ffi与未来 Pythonctypes绑定这条完整生成管线并掌握其消费方qiskit-bindgen-cli的实际用法。定位构建与分发流程中的“头文件生成中枢”根据 crates/bindgen/README.md 的定义qiskit-bindgen是一个仅供构建与分发流程使用的内部库它的核心职责是解析qiskit-cextcrate见 crates/cext暴露出的公开 API生成合适的 C 头文件以便访问该 crate 编译出的库中的函数统管独立头文件生成的全部逻辑包括手写 include 文件include目录、Rust 模板 cratepyo3-ffi目录以及两者的安装逻辑大部分繁重工作由cbindgen完成本 crate 负责“scraping 设置逻辑”——即围绕cbindgen配置展开的定制化预处理。该库本身不直接面向终端用户而是设计给其消费方——二进制工具qiskit-bindgen-clicrates/bindgen-cli使用未来还将被 Python 扩展构建流程qiskit-pyextcrates/pyext复用。README 还预告了一个演进方向未来本库可能提供对cbindgen输出的包装将写出的函数与类型以结构化数据暴露给下游包括 Qiskit 自己的 Python 扩展使下游能直接基于结构化数据生成各语言的原始绑定而不必重新解析生成的 C 头文件。目录结构与三大核心资产crates/bindgen/ ├── Cargo.toml # 依赖声明 ├── README.md # 定位说明 ├── include/ # ① 手写 include 文件随头文件一起安装 │ ├── qiskit.h │ └── qiskit/ │ ├── attributes.h │ ├── complex.h │ ├── funcs_py.h │ └── version.h ├── pyo3-ffi/ # ② Rust 模板 crate安装时复制并覆写生成文件 │ ├── Cargo.toml │ ├── Cargo.lock │ └── src/ │ ├── lib.rs # 手写部分qk_import、declare_fn! 宏 │ └── ffi.rs # 自动生成部分安装时由 qiskit-bindgen 覆写 └── src/ ├── lib.rs # 主入口配置、生成、安装 ├── simple_ir.rs # 简化的 cbindgen 输出 IR └── render/ # 多语言渲染后端 ├── c.rs # C 类型渲染、函数指针 cast ├── ctypes.rs # Python ctypes 渲染未来 Python 绑定 ├── rust.rs # Rust 渲染pyo3-ffi 的 ffi.rs └── mod.rs从 crates/bindgen/Cargo.toml 可以看到它的关键依赖设计qiskit-cext-vtable启用python_bindingfeature提供函数指针槽位表vtable是生成 Rust 绑定时的槽位来源cbindgen启用unstable_irfeature承担 Rust → C 绑定生成的主体力hashbrown、regex、anyhow分别用于哈希映射、文本处理与错误传播。生成管线从 qiskit-cext 到 Bindings核心入口是 crates/bindgen/src/lib.rs 中的generate_bindingspub fn generate_bindings(cext_path: impl AsRefPath) - anyhow::Resultcbindgen::Bindings { cbindgen::Builder::new() .with_crate(cext_path) .with_config(get_config()?) .generate() .map_err(|e| e.into()) }它把cext_path指向的 crate即qiskit-cext交给cbindgen并套用get_config()生成的定制配置。get_config()crates/bindgen/src/lib.rs配置要点如下配置项取值含义languageC输出 C 语言头文件styleStyle::Typetypedef 风格cpp_compattrue与 C 兼容usize_is_size_ttrueRustusize映射为 Csize_tinclude_versiontrue头文件中包含版本信息includesqiskit/attributes.h所有生成文件都包含该文件保证 Doxygen 能识别弃用属性宏parse.parse_depstrue解析依赖 crateparse.includeqiskit-quantum-info、qiskit-circuit、qiskit-transpiler只从这些公开 API crate 导出符号对应常量QISKIT_PUBLIC_API_CRATESdefinesfeature python_binding→QISKIT_C_PYTHON_INTERFACERust cfg feature 到 C#ifdef宏的映射header带版权注释的头部文本由copyright_with_line_comments(//)生成值得注意的细节cbindgen的FunctionConfig被配置为使用自定义的弃用标注宏Qk_DEPRECATED_FN与Qk_DEPRECATED_FN_NOTE({})对应 crates/bindgen/include/qiskit/attributes.h 中定义的宏从而让生成的 C 头文件携带与手写头文件一致的弃用标注语法。函数级属性注解no-export与allow-duplicate在cext源码中函数可以通过cbindgen注解qk-vtable-rules声明特殊属性常量CBINDGEN_ATTRIBUTE_NAME。crates/bindgen/src/lib.rs 定义了FnAttributes结构体支持两种取值no-export该函数应被跳过不出现在任何 vtable 槽位列表中allow-duplicate允许该函数被导出到多个槽位。fn_attrscrates/bindgen/src/lib.rs负责从cbindgen::ir::Function的注解列表中解析这些属性遇到未知属性会直接报错从而保证槽位表与导出函数集合的严格一致。命名与导出约定Qk前缀、重命名映射与 verbatim 导出C 语言没有命名空间因此 Qiskit 的 C API 采用统一前缀Qk常量EXPORT_PREFIX来区分符号。前缀的施加方式并非简单的“一律加前缀”而是通过一张显式的重命名映射EXPORT_RENAMEcrates/bindgen/src/lib.rs完成例如Rust 内部名C API 导出名CBlocksModeQkBlocksModeCDagNeighborsQkDagNeighborsCInstructionQkCircuitInstructionCircuitDataQkCircuitDAGCircuitQkDagSparseObservableQkObsStandardGateQkGateExprQkExprNode实现上get_config()将EXPORT_RENAME逐项拼接Qk前缀构造出cbindgen的rename映射同时设置renaming_overrides_prefixing: true从而让EXPORT_VERBATIM目前只有PyObject可以原样导出、不被加前缀。此外EnumConfig设置了prefix_with_name: true即枚举值会带枚举名前缀例如QkExitCode_Success这样的形式。头文件安装types.h 与 funcs.h 的拆分install_c_headerscrates/bindgen/src/lib.rs负责把生成结果与手写文件一起安装到目标目录关键逻辑是把 cbindgen 输出拆成两个文件qiskit/types.h只写类型与常量通过临时取出bindings.functions实现。代码中还有一个assert!(bindings.globals.is_empty())表明目前尚未出现全局变量/常量一旦出现需要专门处理qiskit/funcs.h只写函数通过临时取出bindings.items与bindings.constants实现。它对应“非 Python 扩展模式”下的函数声明随后递归复制include目录下所有.h/.hpp手写文件manual_include_files只收集扩展名为h或hpp的文件。这两个生成文件的命名常量GENERATED_FILE_TYPES types.h、GENERATED_FILE_FUNCS funcs.h与作用域目录常量SCOPED_INCLUDE_DIR qiskit都定义在 crates/bindgen/src/lib.rs。手写 include 文件伞形头与配套宏include目录中的文件是人工维护、随生成结果一起安装的其中qiskit.h是所有头文件的“伞形入口”crates/bindgen/include/qiskit.h其组织方式如下#if defined(QISKIT_C_PYTHON_INTERFACE) || defined(QISKIT_PYTHON_EXTENSION) #include Python.h #endif #include qiskit/attributes.h #include qiskit/complex.h #include qiskit/version.h #include qiskit/types.h // 由 cbindgen 生成 #if defined(QISKIT_PYTHON_EXTENSION) #include qiskit/funcs_py.h // 由 Qiskit 的 pyext 生成或打桩 #else #include qiskit/funcs.h // 由 cbindgen 生成 #endif这套结构体现了两个设计要点Python 感知构建与普通构建分离当定义了QISKIT_PYTHON_EXTENSIONPython 扩展构建时使用funcs_py.h否则使用funcs.h。当定义了QISKIT_C_PYTHON_INTERFACE即 Rust 侧启用了python_bindingfeature或QISKIT_PYTHON_EXTENSION时才引入Python.h。版本信息的集中维护crates/bindgen/include/qiskit/version.h 定义了QISKIT_VERSION_MAJOR/MINOR/PATCH、发布等级宏QISKIT_RELEASE_LEVEL_DEV/BETA/RC/FINAL以及QISKIT_VERSION_HEX十六进制版本编码格式0xMMmmppls例如 2.1.0rc1 为0x020100C1当前版本为2.6.0-dev。特别值得注意的是 crates/bindgen/include/qiskit/funcs_py.h它只是一个显式报错的桩文件#error ...。当用户拿到的是不含 Python 扩展访问能力的分发版 C API 时直接引用qiskit.h会得到清晰的中断错误而不是难以排查的“文件找不到”预处理错误完整 Python 包构建时会用真正可用的版本覆写它。弃用标注宏Qk_DEPRECATED_FN/Qk_DEPRECATED_FN_NOTE则在 crates/bindgen/include/qiskit/attributes.h 中针对 GCC/Clang__attribute__((deprecated))与 MSVC__declspec(deprecated)分别定义。Rust 模板 crateqiskit-pyo3-ffi 的生成与安装README 明确说明本 crate 拥有pyo3-ffi目录——一个被整体复制安装的 Rust 模板 crate其产物qiskit-pyo3-ffi提供“通过 Python 空间qiskit包访问 Qiskit 原始 C API 的 Rust 绑定”。安装逻辑在install_rust_pyo3_fficrates/bindgen/src/lib.rs先把pyo3-ffi模板目录通过cargo package --list枚举文件原样复制到安装目录然后渲染生成src/ffi.rs覆写同名文件。渲染工作由 crates/bindgen/src/render/rust.rs 完成它针对三个 vtableQK_FFI_CIRCUIT、QK_FFI_TRANSPILE、QK_FFI_QI分别对应qiskit_cext_vtable::FUNCTIONS_CIRCUIT/FUNCTIONS_TRANSPILE/FUNCTIONS_QI遍历槽位导出项为每个函数生成一段declare_fn!(vtable[offset]; name(args) - ret)宏调用。对应的运行时支撑在 crates/bindgen/pyo3-ffi/src/lib.rsqk_import(py)第 142-183 行从 Python 模块qiskit._accelerate.capi中取出三个PyCapsuleQK_FFI_CIRCUIT等把其中存储的函数指针表地址存入三个OnceLockVTablePtr静态变量并有意识地对 capsule 引用做std::mem::forget泄漏使其“不朽”declare_fn!宏第 195-225 行为每个 C API 函数生成#[inline(always)]的unsafe包装函数运行时从vtable静态量按offset取出extern C函数指针再间接调用安全约定除qk_import外的所有函数都是unsafe的且在qk_import成功返回之前一律无效因此通常应在 PyO3 模块初始化函数中先调用ffi::qk_import(m.py())?。crates/bindgen/pyo3-ffi/Cargo.toml 还透露了模板 crate 的分发定位它刻意脱离工作区[workspace]强制排除pyo3依赖范围放宽为0.22,0.28、num-complex为0.4便于作为独立依赖被外部 crate 使用。简化 IR 与多语言渲染后端由于 Qiskit 需要向多种“非 C”语言/格式输出绑定Rust 已实现、Python ctypes 已具备、未来可能更多crates/bindgen/src/simple_ir.rs 定义了一套比 cbindgen 输出更精简、更结构化的中间表示只保留 Qiskit 实际用到的元素TypeT带指针层级ptrs从最内层向外排列如*mut *const T表示为ptrs: [Const, Mut]与基础类型内置/自定义Enum导出名、底层整数表示repr与(name, literal)变体列表StructT可选字段fields: None表示不透明 struct、UnionT不可为不透明的 unionFunctionT导出名、参数可无名与返回类型ItemsT上述四类对象的集合Default实现为空集合。render目录下的三个后端各司其职crates/bindgen/src/render/rust.rs将 IR 渲染为 Rust 源码——枚举派生Clone, Copy, PartialEq, Eq, Hash, Debug并带#[repr(...)]透明 struct 字段全部pub且#[repr(C)]不透明 struct 采用 Rustonomicon 推荐的PhantomData(*mut u8, PhantomPinned)表示法函数渲染为declare_fn!宏调用crates/bindgen/src/render/ctypes.rs将 IR 渲染为 Pythonctypes模块源码——输出__all__、import ctypes/enum、ctypes.PyDLL(...)声明、枚举对应的class X(enum.Enum)变体用底层ctypes构造函数如ctypes.c_int32(0)赋值、struct 对应的class X(ctypes.Structure)含_fields_、函数对应的argtypes/restype赋值并注意声明顺序不透明 struct 最先、union 其次、透明 struct 最后以保证 Python 自上而下执行时引用合法它还内置了一个QkComplex64隐式定义两个double字段re/imcrates/bindgen/src/render/c.rsC 类型渲染与“导出函数名 → C 函数指针 cast 类型”的映射functions_as_funcptr_casts供 ABI 校验等场景使用。从渲染器的代码注释可以清楚看到当前的能力边界数组类型、函数指针在simple_ir路径中、可变参数VaList都尚未支持遇到会直接bail!报错——这些是未来扩展的空间。消费方qiskit-bindgen-cli 的使用方式qiskit-bindgen-clicrates/bindgen-cli/src/main.rs是当前唯一消费者用clap定义了一组子命令cext_path统一用-c/--cext-path指定输出目录用-o/--output-path子命令作用关键参数install生成并安装 C 头文件到指定目录内部调用generate_bindingsinstall_c_headers-c cext_path、-o output_pathshow-slots打印当前版本所有已占用的 vtable 槽位表示无lint-slots校验槽位表与当前版本导出函数列表的一致性-c cext_pathgenerate-pyo3生成 Rust 模板 crate 输出install_rust_pyo3_ffi-c cext_path、-o output_pathcheck-abi校验两套槽位导出之间满足语义化版本约束只检查符号名与偏移不检查函数指针类型old 旧槽位文件、new [新槽位文件]缺省时对比当前 vtable 定义这组命令把“生成头文件”“生成 Rust 绑定”“ABI 兼容性检查”三个构建期需求完整覆盖也呼应了 README 中“该库设计给其消费二进制使用”的定位。未来演进与设计意图README 结尾描述的演进方向为cbindgen输出提供包装、以结构化数据暴露函数与类型在当前代码中已有明显铺垫simple_ir与三个render后端正是“从结构化中间表示出发、向任意语言导出”的基础设施ctypes.rs的 Python 输出能力已经相当完整只待接入实际构建流程。对于想要深入 Qiskit C API 生成机制的读者建议按以下顺序研读crates/bindgen/src/lib.rs理解配置、生成、安装三段式主流程crates/bindgen/src/simple_ir.rs理解跨语言中间表示crates/bindgen/src/render/rust.rs 与 crates/bindgen/pyo3-ffi/src/lib.rs理解 Rust 绑定如何与 vtable 槽位对接crates/bindgen/include/qiskit.h理解最终交付给 C/C 使用者的头文件形态crates/bindgen-cli/src/main.rs理解整套工具链如何在构建脚本中被调用。赞分享科学计算【免费下载链接】qiskitQiskit is an open-source SDK for working with quantum computers at the level of extended quantum circuits, operators, and primitives.项目地址https://gitcode.com/gh_mirrors/qi/qiskit点击查看免费下载相关推荐使用 Bindgen 自动生成 FFI 绑定comprehensive-rust 中 C 头文件到 Rust 的桥梁使用 Bindgen 自动生成 FFI 绑定comprehensive rust 中 C 头文件到 Rust 的桥梁 导读 在 Android 平台开发中R文档教程Cleanlab 内部 neighbor 模块解析KNN 图构建、最近邻搜索与距离度量选择Cleanlab 内部 neighbor 模块解析KNN 图构建、最近邻搜索与距离度量选择 neighbor 是 Cleanlab 内部 cleanlab.科学计算RevokeMsgPatcher5 分钟给微信/QQ/TIM 打上防撤回补丁的完整攻略RevokeMsgPatcher5 分钟给微信/QQ/TIM 打上防撤回补丁的完整攻略 RevokeMsgPatcher 是一款 Windows 防撤回补丁工科学计算上一篇GitHub Readme Streak Stats测试覆盖率提升从70%到95%的实践下一篇OLMo推理服务搭建高并发API设计创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考