Python调用C++代码

news/2025/11/17 22:25:08/文章来源:https://www.cnblogs.com/2bjiujiu/p/19234648

Python调用C++代码

1. extern "C" {} 包裹导出函数

// C++ 中存在名称修饰,通过 extern "C" {} 将C++函数导出为C函数
// 1. 为类的每个函数创建C风格接口,第一个参数为对象指针
// 2. 提供 create(构造) destroy(析构) 函数管理对象的生命周期
#include <string>// C++类定义
class Calculator {
private:
int base;
public:
Calculator(int b) : base(b) {}
int add(int a) { return base + a; }
std::string greet(const std::string& name) { return "Hello, " + name; }
};// C风格函数
extern "C" {// 创建对象(对应构造函数)
Calculator* Calculator_create(int base) {
return new Calculator(base);
}// 销毁对象(对应析构函数)
void Calculator_destroy(Calculator* obj) {
delete obj;
}// 封装成员函数
int Calculator_add(Calculator* obj, int a) {
return obj->add(a);
}// 字符串处理需要特殊转换(C++ string -> char*)
const char* Calculator_greet(Calculator* obj, const char* name) {
static std::string result;  // 注意:静态变量在多线程中不安全
result = obj->greet(std::string(name));
return result.c_str();
}}

2. 将C++代码编译为动态库

# 使用C++编译器,保留 -f PIC -shared 参数生成位置无关的动态库
g++ -shared -fPIC -o libcalc.so example.cpp

3. 使用python的ctypes库调用动态库(加载动态库 -> 定义C函数的输入参数与返回参数 -> 调用动态库函数)

  • 用 c_void_p 类型存储C++对象的指针
  • 字符串通过bytes类型转换(encode/decode)
  • 实现 del 方法自动释放C++对象,避免内存泄漏
import ctypes
import osclass CalculatorWrapper:"""C++ Calculator类的Python封装器"""def __init__(self):# 加载动态库self.lib = self._load_library()# 配置C接口函数原型self._setup_functions()# 存储C++对象指针self.obj_ptr = Nonedef _load_library(self):"""根据操作系统加载对应的库文件"""try:if os.name == "nt":return ctypes.CDLL("./calc.dll")elif os.name == "posix":return ctypes.CDLL("./libcalc.so")else:raise OSError("不支持的操作系统")except OSError as e:raise RuntimeError(f"加载库失败: {e}")def _setup_functions(self):"""定义C接口函数的参数类型和返回值类型"""# 创建对象self.lib.Calculator_create.argtypes = [ctypes.c_int]self.lib.Calculator_create.restype = ctypes.c_void_p  # 返回对象指针# 销毁对象self.lib.Calculator_destroy.argtypes = [ctypes.c_void_p]self.lib.Calculator_destroy.restype = None# 加法函数self.lib.Calculator_add.argtypes = [ctypes.c_void_p, ctypes.c_int]self.lib.Calculator_add.restype = ctypes.c_int# 字符串问候函数self.lib.Calculator_greet.argtypes = [ctypes.c_void_p, ctypes.c_char_p]self.lib.Calculator_greet.restype = ctypes.c_char_pdef create(self, base_value):"""创建C++ Calculator实例"""self.obj_ptr = self.lib.Calculator_create(base_value)if not self.obj_ptr:raise RuntimeError("创建C++对象失败")def add(self, a):"""调用加法方法"""self._check_object()return self.lib.Calculator_add(self.obj_ptr, a)def greet(self, name):"""调用问候方法(处理字符串转换)"""self._check_object()# Python字符串转C字符串(bytes类型)c_name = name.encode('utf-8')result_ptr = self.lib.Calculator_greet(self.obj_ptr, c_name)# C字符串转Python字符串return result_ptr.decode('utf-8')def _check_object(self):"""检查对象是否已创建"""if not self.obj_ptr:raise RuntimeError("请先调用create()创建对象")def __del__(self):"""对象销毁时自动释放C++资源"""if self.obj_ptr:self.lib.Calculator_destroy(self.obj_ptr)if __name__ == "__main__":try:calc = CalculatorWrapper()calc.create(100)  # 初始化base值为100print(f"100 + 50 = {calc.add(50)}")  # 输出150print(calc.greet("C++"))  # 输出"Hello, Python"except Exception as e:print(f"错误: {e}")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/968364.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

复杂状态与数据流管理:分布式定时任务系统的设计

好的,这是一个非常考验系统设计深度的问题。下面我将详细拆解这个“分布式定时任务系统”的设计,重点阐述如何解决可靠性和幂等性这两个核心挑战。复杂状态与数据流管理:分布式定时任务系统的设计 在GM平台中,定时…

【第6章 字符串】Python 字符串常用操作完全教程(含代码演示)

{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Python 字符串常用操作完全教程(含代码演示)\n", "> 基于《Pytho…

DAG-有向无环图-拓扑排序

1. 场景 通过当前节点与依赖节点列表描述一个有向无环图DAG节点依赖问题,适合流程图中节点依赖关系的定义,适合存在明确的依赖关系并且按依赖顺序执行的领域项目管理与任务调度 工作流与审批流程2. 数据描叙name:描…

MySQL EXPLAIN中的key_len:精准掌握索引使用情况

深入解析MySQL执行计划中最关键的指标之一,助你快速定位索引优化点,提升查询性能!同时介绍了key_len计算的核心规则。MySQL系列文章 深入解析MySQL执行计划中最关键的指标之一,助你快速定位索引优化点,提升查询性…

1090 : 分解因数 25-11-17

|DFS|递归| 本题的dfs特点在于搜索的空间是动态的,因此需要找到可以利用到限制下一步递归的条件来进行空 间范围的缩小与框定。本题利用的是分解的最小因数,可以对下一步的遍历框定范围 #include<iostream> #i…

NOIP 模拟赛 9

NOIP 模拟赛总结 NOIP 模拟赛 9调了一整场的 T2,样例全过!只有 40 pts。QxQT1 卡门连续两场 T1 放数据结构了欸数据结构题,直接分块就行。 赛时没算时间复杂度,导致打了个暴力交上去以为是正解。 赛后半小时改完,…

Sora 2 Cameo多角色上传+Remix二创功能API接入教程,史低0.08/条

​ 你还记得Sora2推出的Cameo和Remix功能吗? Cameo(客串)是 Sora 2 推出的官方真人出镜功能,允许用户通过录制验证视频,将自己的面部、体型、声音特征提取并融合到 AI 生成的任意场景中,实现"真人演员+虚拟场景…

info linux

当然可以!你提到的 + #引号 + info linux + #引号 + 是一个在 Linux 系统中常用的命令,用于查看 Linux 内核的文档。它属于 info 命令集,是 man 命令的替代品,主要用于查看系统级的文档。 一、info 命令简介…

AWS云服务深度集成

第一部分:素材管理系统 - 分片上传与断点续传架构 在海量素材上传场景下,网络不稳定、文件巨大(数GB的视频/设计稿)是常态。直接简单上传会导致频繁失败且难以恢复。我们基于 AWS S3 Pre-signed URLs 和 Multipart…

httpd linux 启动

在 Linux 系统中,httpd 通常指的是 Apache HTTP Server,它是一个常用的 Web 服务器软件。如果你想要启动 Apache HTTP Server,可以使用以下几种常见方法:方法一:使用 systemd(适用于大多数现代 Linux 发行版) s…

浅谈 Manacher

问题引入 给定一个长度为 \(n\) 的字符串 \(s\),保证 \(s\) 只由小写字母组成,要求计算出 \(s\) 中最长的连续回文子串的长度。 乍一看,诶我会 \(O(n^3)\) 做法!枚举左右端点然后暴力判断就行。 但是这也太慢了吧!…

第28天(简单题中等题 二分查找)

打卡第二十八天 1道简单题+2道中等题题目:思路:双指针+二分查找 代码: class Solution { public:vector<int> kthSmallestPrimeFraction(vector<int>& arr, int k) {const int n = (int)arr.size();//…

基于MIMO系统的SCMA稀疏码多址接入和MPA消息传递算法matlab仿真

1.算法运行效果图预览2.算法运行软件版本 matlab2022a/matlab2024b 3.部分核心程序 (完整版代码包含详细中文注释和操作步骤视频)................................................................r = de2bi(X, l…

Node.js服务稳定性保障:从热更新到高可用体系

好的,这些问题深入到了Node.js后端架构的核心。下面我将为您系统地拆解这些挑战和我们的解决方案。Node.js服务稳定性保障:从热更新到高可用体系 第一部分:渲染服务的热更新原理与高并发保障 我们的官网/商城渲染服…

一次尝试,3个小时90元的主机游玩和F1电影

一次尝试,3个小时90元的主机游玩和F1电影2025年11月16日 星期日 早上去中影烽禾影城泛悦奥莱店(马房山店),花了90块钱,在PS5上面玩了将近三个小时的风之旅人,比我想象之中的还要可怕,我的忘性大的吓人,除了那个红…

NOIP 模拟赛 8

呜呜呜,直接叫 T1 模拟赛吧。NOIP 模拟赛总结 NOIP 模拟赛 8呜呜呜,直接叫 T1 模拟赛吧。T1 王哥与荷塘(fish) 发现要求的是曼哈顿距离的最远点对。 根据 HZ战神 王战普老师的教导可知。 任意两点的曼哈顿距离可以…

静态路由的配置

11.17配置静态路由实验1、拓扑结构:两台PC机,两台交换机Router 2、连线:PC与Router交叉线连接FastEthernet0/0 Router之间DCE串口线连接Serial2/0口 3、打开接口 Router0和Router1 enable //进入特权模式 config…

读书笔记:“外部表”的进阶使用,它主要解决了三个核心问题:如何切换文件、多用户怎么办,以及一个非常酷的玩法——把系统命令变成表。

我们的文章会在微信公众号IT民工的龙马人生和博客网站( www.htz.pw )同步更新 ,欢迎关注收藏,也欢迎大家转载,但是请在文章开始地方标注文章出处,谢谢! 由于博客中有大量代码,通过页面浏览效果更佳。本文为个人学…

[CF 2166D] Marble Council

思路 肯定是在值域上处理, 类似今年 S T4 的将与未扫描部分相关的部分单独统计 定义 \(c_x\) 为 \(a_i = x\) 的数量 考虑 \(f_{i, j, k}\) 表示考虑到数字 \(i\), 当前要求容量到 \(j\), 当前容量为 \(k\) 的方案数 \…

DP 复习

背包 DP 背包 dp 解决形如用一些物品,有一些限制,装满这个容量的方案/最小代价。 四种板子01背包,循环从高到低 完全背包,循环从低到高 多重背包,二进制分组(低到高)然后01背包 分组背包,每组在最内层,外层跑…