跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Python

使用 Boost::Python 将 C++ 库封装为 Python 扩展

综述由AI生成在跨语言系统交互中,因不同语言对 JSON Schema 标准版本支持不一致导致的问题。解决方案是利用 C++ 编写统一的核心库,并通过 Boost::Python 将其封装为 Python 扩展模块。内容涵盖从环境配置、C++ 类封装、编译动态库、使用 distutils 构建安装到最终测试验证的完整流程。同时补充了常见链接错误排查及打包分发的建议,帮助开发者实现高性能的 Python 功能扩展。

CodeArtist发布于 2025/2/6更新于 2026/6/222 浏览
使用 Boost::Python 将 C++ 库封装为 Python 扩展

前言

在构建大型分布式系统时,为了保证数据在系统上下游的自动校验,避免数据结构异常带来的系统稳定性问题,通常会采用 JSON 格式进行数据交互。此时,可以采用 JSON Schema 来定义接口规范,并利用 JSON Schema Validator 来校验接口响应结构的合法性。

然而,系统中不同子系统的实现语言往往并非一致。虽然主流编程语言都提供了 JSON Schema Validator 的具体实现,但不同语言支持的 JSON Schema 标准版本(Draft)并不完全统一,这会给后续的系统集成带来混乱。例如:

  • Java: json-schema-validator 支持 Draft 4
  • C++: json-schema-validator 支持 Draft 7
  • Python: jsonschema 支持 Draft 7

目前大多数语言(如 Java, Golang, PHP, Lua 等)都支持 C/C++ 的扩展机制。因此,最佳实践是用 C/C++ 编写核心逻辑库,再为其他语言提供统一的扩展包。本文详细介绍如何利用 Boost::Python 库将 C++ 的 nlohmann_json_schema_validator 封装为 Python 扩展,并介绍如何使用 distutils 进行编译与分发。

Python 调用 C/C++ 的方式

主要有两种方式可以实现 Python 调用 C/C++ 编写的库:

  1. ctypes:Python 内置的外部函数库,提供 C 兼容的数据类型,允许在 DLL 或共享库中调用函数。
  2. Python Extension API:Python 官方提供的扩展机制,通过编写 C/C++ 代码生成 .so (Linux/Mac) 或 .pyd (Windows) 文件,被 Python 解释器直接加载。

ctypes 加载 so 文件

ctypes 是 Python 封装的 API 函数库。其中 cdll = <ctypes.LibraryLoader object> 是一个库加载器对象,调用 cdll.LoadLibrary 便可调用 C/C++ 的 so 库。

import ctypes
lib = ctypes.CDLL('./libmylib.so')
lib.my_function.argtypes = [ctypes.c_int]
lib.my_function.restype = ctypes.c_int
result = lib.my_function(10)

此处不再对如何使用 ctypes 模块加载 so 文件做过多的介绍,具体可以参考其官方文档。对于复杂的类封装和内存管理,直接使用 ctypes 较为繁琐且容易出错。

使用 Python 扩展

该方式是 Python 为整合其它语言而提供的一种扩展机制。Python 的可扩展性具有如下优点:

  1. 方便为语言增加新功能
  2. 具有高度可定制性
  3. 可以实现底层代码复用
  4. 性能更优(相比 ctypes 的边界转换开销)

该方式的具体使用可以参考 Python 官方文档 Building C and C++ Extensions。接下来要讲的例子就是利用了'代码复用'的优点。

Python 提供了 Python/C++ API 用来实现 Python 和 C++ 的交互。然而,直接使用这些 API 来完成交互会存在很多重复工作,例如手动处理引用计数、类型转换等。Boost::Python 则对 Python/C++ API 进行了抽象和包装,使得 Python 和 C++ 的交互更加方便,类似于 pybind11 但基于 Boost 生态。

Boost::Python 封装 C/C++ 扩展

接下来我们介绍如何利用 Boost::Python 为 nlohmann_json_schema_validator 增加 Python 支持。

nlohmann_json_schema_validator 是一个基于 JSON Schema 验证 JSON 文档的 C++ 库,它本身应验证符合 JSON Schema Validation draft-7 标准。

编译 nlohmann json schema validator 库

该库支持产出可执行的 bin 文件以及可供其他项目使用的动态库。为了可以将该扩展包装成 Python 扩展,我们需要先生成该库的动态库。

首先根据 nlohmann_json_schema_validator 的编译文档编译出动态库。通常需要使用 CMake 配置,确保开启 BUILD_SHARED_LIBS 选项。

Boost::Python 封装 C/C++ 代码

在安装 Boost 的时候,虽然 Boost 的头文件中存在 Boost::Python 相关的 hpp 文件,但是默认却没有该动态库。因此,在使用 Boost::Python 之前,首先需要安装该库。

# macOS 示例
brew install boost-python3

# Linux 示例 (Ubuntu/Debian)
sudo apt-get install libboost-python-dev

然后,我们用 C++ 编写 class json_validator_python 来封装 nlohmann_json_schema_validator 库,并利用 Boost::Python 来导出。

// jsv_python.cpp
#include <iomanip>
#include <iostream>

#include <nlohmann/json-schema.hpp>
#include <boost/python.hpp>

using namespace boost::python;

class JSON_SCHEMA_VALIDATOR_API json_validator_python
{
private:
    nlohmann::json_schema::json_validator validator;

public:
    json_validator_python() {}
    
    void set_root_schema(const std::string &json_string) 
    {
        // 解析 JSON 字符串
        auto parsed = nlohmann::json::parse(json_string.begin(), json_string.end());
        validator.set_root_schema(parsed);
    }

    void validate(const std::string &json_string) const
    {
        // 解析并验证
        auto data = nlohmann::json::parse(json_string.begin(), json_string.end());
        validator.validate(data);
    }
};

// json_schema_validator 为 module 名,必需和生成的 so 库名一样
BOOST_PYTHON_MODULE(json_schema_validator)
{
    class_<json_validator_python, boost::noncopyable>("json_validator_python")
            .def("set_root_schema", &json_validator_python::set_root_schema)
            .def("validate", &json_validator_python::validate)
            ;
}

如上所示的 BOOST_PYTHON_MODULE 代码,目的是导出类及成员方法。这些导出的类和方法可以在 Python 中直接导入并实例化。关于 Boost::Python 更详细的使用,可以参考其官方文档。

编译并产出 Python 扩展

使用 g++ 进行编译。注意需要指定正确的头文件路径和库路径。

# 1. 编译目标文件
export JSON_SCHEMA_PATH=/path/to/nlohmann-json-schema-validator
export BOOST_PATH=/usr/local/opt/boost
export PYTHON_INCLUDE=$(python3-config --includes)

g++ --std=c++11 -fPIC -c jsv_python.cpp \
-I${JSON_SCHEMA_PATH}/src \
-I/usr/include/nlohmann \
-I${BOOST_PATH}/include \
-I${PYTHON_INCLUDE}

# 2. 链接生成共享库
g++ --std=c++11 -shared \
-L${JSON_SCHEMA_PATH}/build/lib \
-L${BOOST_PATH}/lib \
-L$(python3-config --prefix)/lib \
-lnlohmann_json_schema_validator \
-lboost_python38 -lpython3.8 \
-o json_schema_validator.so jsv_python.o

如上的指令,会生成封装之后的 Python 扩展:json_schema_validator.so。

测试 python 扩展

在当前目录执行如下的 Python 代码,可以发现,我们封装的扩展已经可以当做 Python 扩展来导入并使用了。

import json_schema_validator as jsv

validator = jsv.json_validator_python()

isValidator = True
try:
    # 设置根 Schema
    validator.set_root_schema('{"type":"object", "properties": {"a":{"type": "string"}}}')
    # 验证数据
    validator.validate('{"a":"1"}');
except Exception as e:
    print(f"Validation Error: {e}")
    isValidator = False

print(isValidator)

使用 distutils 编译并分发扩展

为了使用方便,推荐使用 distutils 或 setuptools 模块编译 Python 扩展,这样可以自动化处理依赖路径。

创建 setup.py 文件:

from distutils.core import setup, Extension
import os

os.environ["CC"] = "g++"
os.environ["CXX"] = "g++"

module1 = Extension('json_schema_validator',
                    include_dirs = ['../../src',
                        '../../',
                        '/usr/local/opt/boost/include'],
                    libraries = ['boost_python38', 'python3.8',
                        'nlohmann_json_schema_validator'],
                    library_dirs = ['/usr/local/opt/boost/lib',
                        '.'],
                    sources = ['jsv_python.cpp'],
                    extra_compile_args=['--std=c++11'],
                    extra_link_args=['--std=c++11'])

setup(
    name='json-schema-validator',
    version='1.0',
    description='json schema validator extension',
    ext_modules=[module1]
)

执行以下命令进行构建和安装:

$ python3 setup.py build
$ python3 setup.py install

安装后,可能需要设置环境变量以便运行时能找到动态库:

# macOS / Linux
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib/python3.8/site-packages/json_schema_validator

常见问题与排查

在实际开发过程中,可能会遇到以下常见问题:

1. 找不到模块错误

如果报错 ImportError: No module named json_schema_validator,请检查以下几点:

  • 确认 setup.py 中的 name 参数与生成的 .so 文件名一致。
  • 确认 Python 环境是否正确激活。
  • 检查 sys.path 是否包含了安装目录。

2. 动态库链接错误

如果运行时报错 undefined symbol 或 library not found,通常是链接顺序或路径问题。

  • 确保 -L 参数指向了包含 .so 文件的目录。
  • 确保 -l 参数对应的库名称正确(去掉前缀 lib 和后缀 .so)。
  • 在 macOS 上,可能需要设置 DYLD_LIBRARY_PATH 而不是 LD_LIBRARY_PATH。

3. 跨平台兼容性

  • Windows: 动态库后缀为 .pyd,依赖项需放在同一目录下或通过 PATH 环境变量添加。
  • Linux: 注意 glibc 版本兼容性,尽量在较新的系统上编译。
  • macOS: 注意架构兼容性(x86_64 vs arm64),建议使用 Universal 二进制或针对当前架构编译。

进阶:打包为 Wheel

为了更方便地分发,建议将扩展打包为 Wheel 格式(.whl)。这需要安装 wheel 包并使用 bdist_wheel 命令。

pip install wheel
python setup.py bdist_wheel

生成的 .whl 文件可以直接通过 pip install 安装,无需用户自行编译 C++ 代码,极大降低了部署成本。

总结

本文详细介绍了利用 Boost::Python 将 C++ 库封装为 Python 扩展的完整流程。从环境准备、C++ 代码封装、编译链接到最终的分发测试,涵盖了关键步骤。通过这种方式,开发者可以利用 C++ 的高性能特性增强 Python 应用的功能,同时保持 Python 开发的便捷性。在处理跨语言数据交互和性能敏感模块时,这种混合编程模式是非常有效的解决方案。

目录

  1. 前言
  2. Python 调用 C/C++ 的方式
  3. ctypes 加载 so 文件
  4. 使用 Python 扩展
  5. Boost::Python 封装 C/C++ 扩展
  6. 编译 nlohmann json schema validator 库
  7. Boost::Python 封装 C/C++ 代码
  8. macOS 示例
  9. Linux 示例 (Ubuntu/Debian)
  10. 编译并产出 Python 扩展
  11. 1. 编译目标文件
  12. 2. 链接生成共享库
  13. 测试 python 扩展
  14. 使用 distutils 编译并分发扩展
  15. macOS / Linux
  16. 常见问题与排查
  17. 1. 找不到模块错误
  18. 2. 动态库链接错误
  19. 3. 跨平台兼容性
  20. 进阶:打包为 Wheel
  21. 总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 滑动窗口算法详解:结合例题讲解解题思路(C++)
  • MiniMax 海螺 AI 视频:图片与文本生成高质量视频
  • Web 服务架构与 I/O 模型详解
  • Docker 部署 Music-Tag-Web 音乐标签编辑器
  • Python 开源 AI 模型引入与测试全流程实战
  • 线性动态规划经典四题详解:台阶、最大子段和、传球游戏与乌龟棋
  • Java 类加载机制与双亲委派模型深度解析
  • UniApp WebView H5 与原生应用双向通信实战
  • AIGC 影视创作与提效工具实战指南
  • Linux 信号机制深度剖析:从信号捕捉到 SIGCHLD 处理
  • Spring Boot Web 后端开发:核心注解全解
  • macOS 下升级 Python 的几种主流方案
  • MC.JS WEBMC 在在线教育中的应用案例
  • Python+Agent 入门实战:零基础搭建可复用 AI 智能体
  • 鸿蒙 Next 应用配置文件
  • 自然语言处理在金融领域的应用与实战
  • MCP 协议详解:与 Function Call 的区别及 Python 使用指南
  • AI 辅助开发实战:用 DeepSeek 构建贪吃蛇游戏
  • AI 零基础入门:从概念到实践指南
  • C++ 初学者核心概念与常见误区解析

相关免费在线工具

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online