在Python和C/C++之间共享std::vector<std::vector<int>>数据

在Python和C/C++之间共享std::vector<std::vector>数据

在Python和C/C++之间共享嵌套向量数据(std::vector<std::vector<int>>)可以通过几种方法实现。以下是几种常见的方法:

方法1: 使用Cython

Cython是连接Python和C++的很好选择,它可以直接处理C++ STL容器。

  1. 创建.pyx文件(例如vector_sharing.pyx):
# distutils: language = c++
# distutils: extra_compile_args = -std=c++11from libcpp.vector cimport vectorcdef extern from *:"""std::vector<std::vector<int>> process_vectors(const std::vector<std::vector<int>>& input) {std::vector<std::vector<int>> result;for (const auto& inner : input) {std::vector<int> temp;for (int val : inner) {temp.push_back(val * 2);  // 示例处理}result.push_back(temp);}return result;}"""vector[vector[int]] process_vectors(const vector[vector[int]]& input)def process_vectors_py(list input_list):cdef vector[vector[int]] cpp_inputcdef vector[int] temp# 将Python列表转换为C++ vector<vector<int>>for inner_list in input_list:temp = inner_listcpp_input.push_back(temp)# 调用C++函数cdef vector[vector[int]] result = process_vectors(cpp_input)# 将结果转换回Python列表py_result = []for inner in result:py_result.append(inner)return py_result

方法2: 使用pybind11

pybind11是一个轻量级的C++库,用于将C++代码暴露给Python。

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <vector>namespace py = pybind11;std::vector<std::vector<int>> process_vectors(const std::vector<std::vector<int>>& input) {std::vector<std::vector<int>> result;for (const auto& inner : input) {std::vector<int> temp;for (int val : inner) {temp.push_back(val * 2);  // 示例处理}result.push_back(temp);}return result;
}PYBIND11_MODULE(vector_example, m) {m.def("process_vectors", &process_vectors, "Process nested vectors");
}

编译后,在Python中可以这样使用:

import vector_exampleinput_data = [[1, 2, 3], [4, 5, 6]]
result = vector_example.process_vectors(input_data)
print(result)  # 输出: [[2, 4, 6], [8, 10, 12]]

方法3: 使用ctypes和C接口

如果你不想使用C++ STL,可以创建一个C接口:

  1. C++代码(vector_interface.cpp):
#include <vector>extern "C" {// 创建二维向量void* create_vector2d() {return new std::vector<std::vector<int>>();}// 添加一维向量void add_vector1d(void* vec2d, int* data, int size) {auto& v = *reinterpret_cast<std::vector<std::vector<int>>*>(vec2d);v.emplace_back(data, data + size);}// 处理数据void process_vectors(void* vec2d) {auto& v = *reinterpret_cast<std::vector<std::vector<int>>*>(vec2d);for (auto& inner : v) {for (auto& val : inner) {val *= 2;  // 示例处理}}}// 获取数据int* get_inner_array(void* vec2d, int outer_idx, int* size) {auto& v = *reinterpret_cast<std::vector<std::vector<int>>*>(vec2d);*size = v[outer_idx].size();return v[outer_idx].data();}// 释放内存void free_vector2d(void* vec2d) {delete reinterpret_cast<std::vector<std::vector<int>>*>(vec2d);}
}
  1. Python代码:
import ctypes
import numpy as np# 加载共享库
lib = ctypes.CDLL('./vector_interface.so')  # 或 .dll 在Windows上# 定义函数原型
lib.create_vector2d.restype = ctypes.c_void_p
lib.add_vector1d.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_int), ctypes.c_int]
lib.process_vectors.argtypes = [ctypes.c_void_p]
lib.get_inner_array.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.POINTER(ctypes.c_int)]
lib.get_inner_array.restype = ctypes.POINTER(ctypes.c_int)
lib.free_vector2d.argtypes = [ctypes.c_void_p]def process_data(py_data):# 创建二维向量vec2d = lib.create_vector2d()# 添加数据for inner_list in py_data:arr = (ctypes.c_int * len(inner_list))(*inner_list)lib.add_vector1d(vec2d, arr, len(inner_list))# 处理数据lib.process_vectors(vec2d)# 获取结果result = []for i in range(len(py_data)):size = ctypes.c_int()ptr = lib.get_inner_array(vec2d, i, ctypes.byref(size))result.append([ptr[j] for j in range(size.value)])# 释放内存lib.free_vector2d(vec2d)return result# 使用示例
input_data = [[1, 2, 3], [4, 5, 6]]
output = process_data(input_data)
print(output)  # 输出: [[2, 4, 6], [8, 10, 12]]

方法4: 使用NumPy和C++

如果性能是关键,可以使用NumPy数组并通过C接口传递:

  1. C++代码:
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <vector>namespace py = pybind11;py::array_t<int> process_nested_arrays(py::array_t<int> input) {py::buffer_info buf = input.request();if (buf.ndim != 2)throw std::runtime_error("Number of dimensions must be 2");int* ptr = static_cast<int*>(buf.ptr);size_t rows = buf.shape[0];size_t cols = buf.shape[1];// 处理数据 (这里简单地将每个元素乘以2)for (size_t i = 0; i < rows; i++) {for (size_t j = 0; j < cols; j++) {ptr[i * cols + j] *= 2;}}return input;
}PYBIND11_MODULE(numpy_example, m) {m.def("process_nested_arrays", &process_nested_arrays, "Process nested arrays");
}
  1. Python代码:
import numpy as np
import numpy_example# 创建2D NumPy数组
input_data = np.array([[1, 2, 3], [4, 5, 6]], dtype=np.int32)# 处理数据
output = numpy_example.process_nested_arrays(input_data)
print(output)

性能考虑

  1. 数据拷贝:大多数方法需要在Python和C++之间拷贝数据,这可能成为性能瓶颈。
  2. 内存共享:对于大型数据集,考虑使用内存映射或共享内存来避免拷贝。
  3. 不规则嵌套:如果内部向量长度不一致,NumPy方法可能不太适用,此时pybind11或Cython更合适。

选择哪种方法取决于你的具体需求、性能要求和开发环境偏好。pybind11通常是最简单和灵活的选择,而NumPy方法在数据规则且需要高性能时最有效。

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

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

相关文章

Linux NVIDIA 显卡驱动安装指南(适用于 RHEL/CentOS)

&#x1f4cc; 一、禁用 Nouveau 开源驱动 NVIDIA 闭源驱动与开源的 nouveau 驱动冲突&#xff0c;需先禁用&#xff1a; if [ ! -f /etc/modprobe.d/blacklist-nouveau.conf ]; thenecho -e "blacklist nouveau\noptions nouveau modeset0" | sudo tee /etc/modpr…

Python爬虫实战:获取千库网各类素材图片,为设计师提供参考

一、引言 在当今设计领域,丰富的素材积累对设计师而言至关重要。千库网作为一个素材资源丰富的平台,拥有海量的各类素材图片。然而,手动从该网站收集素材不仅耗时,而且效率低下。Python 作为一种功能强大的编程语言,具备丰富的库和工具,可用于开发高效的爬虫程序。通过 …

vue截图-html2canvas

使用html2canvas进行截图操作 在 Vue 中使用 ​​html2canvas​​ 将 HTML 元素&#xff08;如包含贝塞尔曲线的 Canvas/SVG&#xff09;转换为图片 下载html2canvas npm install html2canvas在页面中使用&#xff0c;要截取哪个div的内容&#xff0c;先给这个div加一个ref标…

介绍Unity中的Dictionary

在 Unity&#xff08;C#&#xff09;中&#xff0c;Dictionary 是一个非常常用的数据结构&#xff0c;它提供 键值对&#xff08;Key-Value Pair&#xff09; 的存储方式。类似于 Python 的 dict 或 JavaScript 的对象&#xff08;Object&#xff09;&#xff0c;但它是强类型的…

MySQL 常用函数(详解)

目录 一、数学函数1.1 四舍五入函数1.2 求绝对值函数二、日期时间函数2.1 获取当前日期和时间三、字符串函数3.1 字符串拼接函数3.2 提取子字符串函数四、聚合函数4.1 计算平均值函数4.2 计算最大值函数五、转换函数5.1 类型转换函数六、总结MySQL 提供了丰富的内置函数,涵盖了…

SOFA编译-Ubuntu20.04-SOFA22.12

一、事前说明 单纯的编译sofa是很简单的&#xff0c;但是想要同时编译SofaPython3则比较难了&#xff0c;我编译了v22.12分支&#xff0c;其他版本sofa的编译也可以参考此篇教程&#xff0c;需注意的是&#xff1a; 1、确定SOFA需要的Python版本&#xff0c;sofa22.12需要的是…

静态BFD配置

AR2配置 int g0/0/0 ip add 10.10.10.2 quit bfd quit bfd 1 bind peer-ip 10.10.10.1 source-ip 10.10.10.2 auto commit AR1配置 int g0/0/0 ip add 10.10.10.1 int g0/0/1 ip add 10.10.11.1 quit bfd quit bfd 1 bind peer-ip 10.0.12.2 source-ip 10.0.12.1 auto co…

关键字where

C# 中的 where 关键字主要用在泛型约束&#xff08;Generic Constraints&#xff09;中&#xff0c;目的是对泛型类型参数限制其必须满足的条件&#xff0c;从而保证类型参数具备特定的能力或特性&#xff0c;增强类型安全和代码可读性。 约束写法说明适用场景举例C#版本要求w…

Arm核的Ubuntu系统上安装Wireshark

Arm核的Ubuntu系统上安装Wireshark 一、安装wireshark 安装命令&#xff1a; sudo apt-get install wireshark-qt 如下图所示&#xff1a; 安装过程弹出如下界面&#xff1a; 鼠标选择Yes&#xff0c;点回车键确认 安装完成。 二、打开wireshark 输入命令行打开wireshark …

编专利或委托他人编专利属于学术不端行为吗?

原文链接&#xff1a;编专利或委托他人编专利属于学术不端行为吗&#xff1f; 自己编专利或委托他人编专利属于学术不端吗&#xff1f; 5月4日&#xff0c;一篇题为《针对性护理干预在子宫肌瘤围手术期的情绪和生活质量临床应用效果》的论文&#xff0c;受到网友的广泛议论。…

Music AI Sandbox:打开你的创作新世界

AI 和音乐人的碰撞 其实&#xff0c;Google 早在 2016 年就启动了一个叫 Magenta 的项目&#xff0c;目标是探索 AI 在音乐和艺术创作上的可能性。一路走来&#xff0c;他们和各种音乐人合作&#xff0c;终于在 2023 年整出了这个 Music AI Sandbox&#xff0c;并且通过 YouTub…

Java游戏服务器开发流水账(2)开发中Maven的管理

Maven 是一款流行的 Java 项目管理工具&#xff0c;它基于项目对象模型&#xff08;Project Object Model&#xff0c;POM&#xff09;的概念来管理项目的构建、依赖和文档等。游戏服务器开发中也会使用. 项目构建 生命周期管理&#xff1a;Maven 定义了一套清晰的项目构建生…

枚举 · 例8扩展-校门外的树:hard

登录—专业IT笔试面试备考平台_牛客网 代码区&#xff1a; #include<algorithm> #include<iostream> #include<vector>using namespace std; struct TREE{int left,right; }; bool compare(const TREE&a,const TREE& b ){if(a.left!b.left){return…

Windows Server 2025 安装AMD显卡驱动

运行显卡驱动安装程序&#xff0c;会提示出问题。但是此时资源已经解压 来到驱动路径 C:\AMD\AMD-Software-Installer\Packages\Drivers\Display\WT6A_INF 打开配置文件&#xff0c;把这两行替换掉 %ATI% ATI.Mfg, NTamd64.10.0...16299, NTamd64.10.0, NTamd64.6.0, NTamd64.…

为什么 MySQL 用 B+ 树作为数据的索引,以及在 InnoDB 中数据库如何通过 B+ 树索引来存储数据以及查找数据

http://www.liuzk.com/410.html 索引是一种数据结构&#xff0c;用于帮助我们在大量数据中快速定位到我们想要查找的数据。 索引最形象的比喻就是图书的目录了。注意这里的大量&#xff0c;数据量大了索引才显得有意义&#xff0c;如果我想要在 [1,2,3,4] 中找到 4 这个数据&am…

AWS VPC架构师指南:从零设计企业级云网络隔离方案

一、VPC核心概念解析 1.1 核心组件 VPC&#xff1a;逻辑隔离的虚拟网络&#xff0c;可自定义IPv4/IPv6地址范围&#xff08;CIDR块&#xff09; 子网&#xff08;Subnet&#xff09;&#xff1a; 公有子网&#xff1a;绑定Internet Gateway&#xff08;IGW&#xff09;&#…

HuggingFace与自然语言处理(从框架学习到经典项目实践)[ 01 API操作 ]

本教程适用与第一次接触huggingface与相应框架和对nlp任务感兴趣的朋友&#xff0c;该栏目目前更新总结如下&#xff1a; ​​Tokenizer​​&#xff1a; 支持单句/双句编码&#xff0c;自动处理特殊符号和填充。 批量编码提升效率&#xff0c;适合训练数据预处理。Datasets​…

【LeetCode 42】接雨水(单调栈、DP、双指针)

题面&#xff1a; 思路&#xff1a; 能接雨水的点&#xff0c;必然是比两边都低&#xff08;小&#xff09;的点。有两种思路&#xff0c;一种是直接计算每个点的最大贡献&#xff08;也就是每个点在纵向上最多能接多少水&#xff09;&#xff0c;另一种就是计算每个点在横向上…

【嵌入式开发-USB】

嵌入式开发-USB ■ USB简介 ■ USB简介

Visual Studio 项目转Qt项目

1. 先确保qmake 和 minGW &#xff08;g&#xff09; 路径都在系统变量内&#xff1b;或者通过WinR -> cmd 来检测&#xff0c; 如果能够 显示qmake 的信息 &#xff0c; g 的信息 &#xff0c; 就说明设置环境变量成功。 2. 打开项目文件夹&#xff0c;在这里打开cmd, 换…