欢迎光临
我们一直在努力

cppyy: 一个强大的 Python-C++ 互操作性库

目录

1.简介

2.基本原理

3.安装与集成

4.用法示例

5.高级特性

6.优缺点分析

7.常见问题


1.简介

        cppyy 是一款基于 Clang/LLVM 和 Cling 实现的 C++ 与 Python 双向交互库,核心优势是无需手写包装代码,即可实现 Python 对 C++ 代码的直接调用,以及 C++ 对 Python 对象的无缝访问,支持 C++11/14/17/20 等现代标准,适配跨平台开发(Windows/Linux/macOS)。

        核心特征:

1.运行时绑定

  • 无需预编译包装代码

  • 动态加载 C++ 库

  • 实时反射 C++ 类型

2.自动类型转换

  • 基本类型自动转换

  • STL 容器支持

  • 智能指针处理

3.高性能

  • 直接调用 C++,无需中间层

  • 与原生 C++ 性能相近

2.基本原理

cppyy 的底层依赖两大核心组件,实现了 C++ 与 Python 的深度绑定:

  • Clang/LLVM:负责解析 C++ 代码生成抽象语法树(AST),完成类型检查与代码分析,支持复杂的 C++ 特性(模板、命名空间、重载等)。
  • Cling:C++ 交互式解释器,提供运行时的 C++ 代码编译与执行能力,让 Python 可以动态加载并调用 C++ 代码。
  • 绑定机制:通过自动生成的类型桥接层,将 C++ 的类、函数、模板等映射为 Python 可调用的对象,同时支持 C++ 侧直接操作 Python 的列表、字典、函数等对象。

3.安装与集成

1.pip 快速安装(推荐)

适用于大部分场景,自动匹配系统环境的预编译包:

# 基础版
pip install cppyy

# 完整版(含额外工具,如 cppyy-cling 解释器)
pip install cppyy-full

2.源码编译安装(适配自定义 LLVM 版本)

适合需要对接特定 Clang/LLVM 版本的场景(如与项目中的 LLVM 依赖一致):

1)安装依赖

Linux (Ubuntu/Debian):

sudo apt-get install llvm-dev clang-dev libclang-dev cmake g++

Windows:安装 Visual Studio(需勾选 C++ 开发工具) + CMake

macOS:

brew install llvm clang cmake

2)编译安装 cppyy:

git clone https://github.com/wlav/cppyy.git
cd cppyy
mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=<安装路径>
make -j$(nproc)
make install

4.用法示例

1.Python 调用 C++ 函数 / 类

示例 1:调用简单 C++ 函数

import cppyy

# 直接定义 C++ 代码并编译
cppyy.cppdef("""
#include <iostream>
void hello_cpp(const std::string& msg) {
std::cout << "C++ says: " << msg << std::endl;
}

int add(int a, int b) {
return a + b;
}
""")

# 调用 C++ 函数
cppyy.gbl.hello_cpp("Hello from Python!")
result = cppyy.gbl.add(10, 20)
print(f"Python gets result: {result}") # 输出 30

示例 2:调用 C++ 类与模板

import cppyy

cppyy.cppdef("""
#include <vector>
class MyClass {
private:
int m_data;
public:
MyClass(int data) : m_data(data) {}
int get_data() const { return m_data; }
void set_data(int data) { m_data = data; }
};
""")

# 实例化 C++ 类
obj = cppyy.gbl.MyClass(100)
print(obj.get_data()) # 输出 100
obj.set_data(200)
print(obj.get_data()) # 输出 200

# 调用 C++ STL 模板(std::vector)
vec = cppyy.gbl.std.vector[int]()
vec.push_back(1)
vec.push_back(2)
print(f"Vector size: {vec.size()}") # 输出 2
print(f"First element: {vec[0]}") # 输出 1

2.C++ 调用 Python 代码

cppyy 支持在 C++ 中直接导入 Python 模块、调用函数、操作对象:

import cppyy
import math # 待 C++ 调用的 Python 模块

# 将 Python 模块/函数暴露给 C++
cppyy.gbl.math = math
cppyy.gbl.python_abs = abs

# 在 C++ 中调用 Python 函数
cppyy.cppdef("""
void call_python_funcs() {
// 调用 Python math 模块的 sqrt 函数
double res = math.sqrt(16.0);
std::cout << "Python sqrt(16) = " << res << std::endl;

// 调用 Python 内置 abs 函数
int abs_res = python_abs(-10);
std::cout << "Python abs(-10) = " << abs_res << std::endl;
}
""")

# 执行 C++ 中的调用逻辑
cppyy.gbl.call_python_funcs()

3.回调函数(Python 到 C++)

import cppyy

cppyy.cppdef("""
#include <functional>
#include <vector>

void apply_function(const std::vector<double>& vec,
std::function<double(double)> func) {
for (auto& v : vec) {
std::cout << func(v) << std::endl;
}
}
""")

def python_func(x):
return x * x + 2 * x + 1

vec = cppyy.gbl.std.vector[float]([1.0, 2.0, 3.0, 4.0])
cppyy.gbl.apply_function(vec, python_func)

4.内存管理

import cppyy

cppyy.cppdef("""
class Resource {
int* data;
public:
Resource(size_t size) {
data = new int[size];
}
~Resource() {
delete[] data;
}
};
""")

# 自动内存管理
res = cppyy.gbl.Resource(100)

# 手动控制
ptr = cppyy.bind_object(cppyy.gbl.Resource(200), cppyy.gbl.Resource)
# 当不再需要时
cppyy.destruct(ptr)

5.高级特性

1.集成 CMake 项目

对于 C++ 项目,可通过 CMake 配置 cppyy 的头文件与库路径,实现 Python 对项目代码的调用:

cmake_minimum_required(VERSION 3.15)
project(cppyy_demo)

# 查找 cppyy 依赖
find_package(cppyy REQUIRED)

# 添加 C++ 源文件
add_library(mylib SHARED mylib.cpp)

# 链接 cppyy 库
target_link_libraries(mylib PRIVATE cppyy)

# 导出头文件路径(供 Python 侧 include)
target_include_directories(mylib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

Python 侧通过 cppyy.include 和 cppyy.load_library 加载:

import cppyy
cppyy.include("mylib.h") # 导入项目头文件
cppyy.load_library("./libmylib.so") # Linux 动态库
# cppyy.load_library("./mylib.dll") # Windows 动态库

# 调用项目中的 C++ 接口
cppyy.gbl.mylib_func()

2.支持 Qt 框架绑定

针对 Qt 项目,cppyy 可直接解析 Qt 的类与信号槽机制(需确保 Qt 头文件可被 Clang 找到):

import cppyy
cppyy.add_include_path("/usr/include/qt6") # Qt 头文件路径
cppyy.include("QString")
cppyy.include("QPushButton")

# 实例化 Qt 类
qstr = cppyy.gbl.QString("Hello Qt")
print(qstr.toStdString()) # 输出 Hello Qt

3.兼容 C++20 特性

cppyy 支持 C++20 的协程、概念、范围等特性,示例如下:

import cppyy

cppyy.cppdef("""
#include <coroutine>
#include <iostream>

// C++20 协程示例
struct MyCoroutine {
struct promise_type {
MyCoroutine get_return_object() { return {}; }
std::suspend_never initial_suspend() { return {}; }
std::suspend_never final_suspend() noexcept { return {}; }
void return_void() {}
void unhandled_exception() {}
};
};

MyCoroutine coro_func() {
std::cout << "C++20 coroutine running" << std::endl;
co_return;
}
""")

# 调用 C++20 协程函数
cppyy.gbl.coro_func()

4.性能优化

  • 减少类型转换开销:使用 cppyy.bind_object 将 C++ 对象直接绑定到 Python,避免拷贝。
  • 预编译 C++ 代码:通过 cppyy.compile 预编译高频调用的 C++ 代码,提升运行速度。

6.优缺点分析

优点缺点
无需手写包装代码,自动完成 C++ 与 Python 绑定 对复杂宏定义、部分模板特化的支持有限
支持现代 C++ 特性(C++11-C++20) 启动速度略慢(首次解析 C++ 代码需编译时间)
双向交互能力强,C++ 可直接调用 Python 代码 调试难度较高,C++ 侧错误在 Python 中定位不直观
跨平台兼容性好,适配 Windows/Linux/macOS 对第三方库的依赖需要手动配置头文件和库路径

7.常见问题

  • 找不到头文件:通过 cppyy.add_include_path 添加头文件路径,例如 cppyy.add_include_path("/usr/include")。
  • 动态库加载失败:确保动态库路径正确,且库与当前 Python 版本(32/64 位)一致;Linux 下可通过 LD_LIBRARY_PATH 设置库路径。
  • 模板函数调用报错:显式指定模板参数类型,例如 cppyy.gbl.std.vector[int]() 而非 cppyy.gbl.std.vector()。
赞(0)
未经允许不得转载:171主机测评 » cppyy: 一个强大的 Python-C++ 互操作性库
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址